我目前正在处理可以处理任何网格状结构上的操作的抽象代码。代替具体的方法,我一直在尝试开发一个接受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