我目前正在處理可以處理任何網格狀結構上的操作的抽象代碼。代替具體的方法,我一直在嘗試開發一個接受lambda表達式的框架,並基於網格元素之間的方向關係提供功能,並且在試圖將泛型類型返回到這些方法時遇到了麻煩。通用返回類型和lambda函數參數
我有一個像下面這樣的工作方法,它接受一個lambda函數,它在特定方向上查找網格元素,以及一個Consumer在每個元素上執行一些方法。
public static <E> void forEachClockwise(Direction d, Function<Direction, ? extends E> f, Consumer<? super E> c){
/*For each of the orthogonal directions, in order:*/
c.accept(f.apply(d));
/*end For*/
}
而不必每此方法被調用時通過一個元件調查功能的,我決定這將是最好有具有聲明這樣的功能的接口「正交」,和重載forEachClockwise方法接受這個接口的元素。
public static <O extends Orthogonal> void forEachClockwise(Direction d, O center, Consumer<O> c){
forEachClockwise(d, center::findNextByDirection, c);
}
我在這裏使用了泛型,並聲明瞭消費者方法可以在不投射的情況下訪問網格元素的字段。我擔心這是一個糟糕的設計選擇,因爲儘管嘗試了一些不同的東西,正交界面和我創建的測試類沒有編譯沒有警告和沒有強制轉換。
public interface Orthogonal {
public <E extends Orthogonal> E findNextByDirection(Direction a);
}
兩個 '有效' findNextByDirection。我試圖實現是:
/* in Coordinate implements Orthogonal: */
@Override
public <E extends Orthogonal> E findNextByDirection(Direction a) {
return (E) (/*The proper Coordinate*/);
}
而且
@Override
public Coordinate findNextByDirection(Direction a) {
return /*The proper Coordinate*/;
}
//Warning on return type declaration:
/*Type safety: The return type Element for findNextByDirection(Direction) from the type Element needs unchecked conversion to conform to E from the type Orthogonal*/
理想情況下,我想有一個方法是,forEachClockwise(和其他方法)可以接受,它會返回一個調用它的同一個類的元素,而不會投射。座標的findNextByDirection應該返回一個座標,地址應該返回一個地址,單元格應該返回單元格等。我看過的其他問題和答案討論如何脫離使用泛型返回類型的方法,但我還沒有找到關於如何使用這種方法作爲lambda參數的任何提示。
我還沒有試過的一些東西正在創建一個新的findByDirection方法,它接受某種正交和方向作爲參數,或者用正交中定義的某種方法調用forEachClockwise方法,儘管這些方法聽起來像是合理的正如我所嘗試的那樣。我見過的另一種方法是爲接口提供它自己的泛型類型,但是它感覺明顯錯誤並且意圖破壞將每個正交類聲明爲「MyClass implements Orthogonal」
我是否已經完全設計了此接口從一開始就錯誤了,並希望仿製藥做一些他們沒有設計的東西?還是有一種簡單的方法讓一個類調用正確的方法並一般返回它自己類型的元素?
全碼:
package test;
import java.util.function.Consumer;
import java.util.function.Function;
public enum Direction {
NORTH, EAST, SOUTH, WEST;
public static <O extends Orthogonal> void forEachClockwise(Direction d, O center, Consumer<O> c){
forEachClockwise(d, center::findNextByDirection, c);
}
public static <X> void forEachClockwise(Direction d, Function<Direction, ? extends X> f, Consumer<? super X> c){
c.accept(f.apply(d));
forEachExcept(d, f, c);
}
public static <X> void forEachExcept(Direction d, Function<Direction, ? extends X> f, Consumer<? super X> c){
for(int i=0; i<3; i++){
d = Direction.getClockwise(d);
c.accept(f.apply(d));
}
}
public static Direction getClockwise(Direction d){
switch(d){
case EAST:
return SOUTH;
case NORTH:
return EAST;
case SOUTH:
return WEST;
case WEST:
return NORTH;
default:
return null;
}
}
}
interface Orthogonal {
public <E extends Orthogonal> E findNextByDirection(Direction a);
}
class Coordinate implements Orthogonal{
int x;
int y;
public Coordinate(int x, int y){
this.x = x;
this.y = y;
}
public int getX(){
return x;
}
public int getY() {
return y;
}
@Override //Warning on "Coordinate" below. Compiler suggests writing
//entire <E extends Orthogonal> method signature
public Coordinate findNextByDirection(Direction a) {
switch(a){
case NORTH:
return new Coordinate(x+1, y);
case SOUTH:
return new Coordinate(x-1, y);
case EAST:
return new Coordinate(x, y+1);
case WEST:
return new Coordinate(x, y-1);
default:
return null;
}
}
}
這將幫助,如果你能產生一個完整的例子,編譯(含警告)。例如,這種實現正交的編譯沒有警告:'公共類Element實現正交{ @覆蓋公共元素findNextByDirection(A方向){ 回報這一點; } }' – assylias
該代碼段在我的返回類型聲明中編譯時發出警告聲明元素: 「類型安全性:類型元素的findNextByDirection(Direction)元素需要未經檢查的轉換以符合E從類型Orthagonal「 –
你複製了方法簽名(返回一個元素,而不是正交)? – assylias