- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我有这段代码,它使用多个映射来存储一些简单的类。现在我还想根据该项目的 x 位置等来查看一些值。我尝试用泛型和 lambda 做一些事情,但没有成功。另外,如果有更简单的方法来做到这一点,请告诉。我的大部分经验都在 Python 上,所以这在 Java 中可能不实用。
interface Compare {
public <T, P> boolean apply(T obj, P comp);
}
class Utils {
public static <T, P> List<T> retrieve(Collection<T> args, P value, Compare c) {
List<T> r = new ArrayList<T>();
for (T i: args) {
if (c.apply(i, value)) {
r.add(i);
}
}
return r;
}
}
class Point {
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
到目前为止,这还没有引发任何错误,但是当我尝试在 HashMap 上实际使用检索函数时,它不起作用。
Point p = Utils.retrieve(points.values(), 0, (Point p, Integer x) -> {return p.x == x;});
eclipse中有两个错误:
遇到这种情况该如何处理?提前致谢。
最佳答案
您已经非常接近获得所需的代码了。
首先,将通用参数声明移至接口(interface)(正如尊敬的 Esquire Wasserman 在他的评论中建议的那样)。
interface Compare<T, P> {
public boolean apply(T obj, P comp);
}
现在您只需修改调用新玩具的方式即可。我使用以下代码创建了一个 main 方法,它运行良好:
public static void main(String[] args) {
Set<Point> points = new HashSet<>(8);
points.add(new Point(0, 0));
points.add(new Point(1, -1));
points.add(new Point(1, 1));
points.add(new Point(-1, -1));
points.add(new Point(-1, -1));
System.out.println("Set<Point> points:\n" + points);
Compare<Point, Integer> sameX = (p, x) -> p.x == x;
List<Point> matchingPoints =
Utils.<Point, Integer>retrieve(points, 0, sameX);
System.out.println("\nmatchingPoints:\n" + matchingPoints);
}
我使用了一个简单的Set<Point>
在这里,因为我不知道你打算在 Map
中存储什么,但调用Map.values()
将产生 Collection<Point>
就像Set<Point>
一样在这个例子中就是这样。
这样做的原因是您在静态方法名称之前的尖括号中指定通用静态方法的参数类型:Utils.<Point, Integer>retrieve
并且您不将类型放入 lambda 中。这里还值得一提的是,lambda 表达式应该尽可能紧凑,而不是 {return p.x == x;}
你可以简单地拥有 p.x == x
。
但请注意,为了以可读的形式查看输出,您需要覆盖 toString()
方法在你的 Point
类:
@Override
public String toString() {
return "Point(" + x + ", " + y + ")";
}
这将为您提供以下输出:
Set<Point> points:
[Point(-1, -1), Point(0, 0), Point(1, -1), Point(-1, -1), Point(1, 1)]
matchingPoints:
[Point(0, 0)]
(另请注意,您不必将 lambda 移出对 retrieve
方法的调用,但这会使代码更整洁,并且更适合这个狭窄的 Stack Overflow 窗口。)
您的后续评论让我意识到您的Utils.retrieve
除非 Compare
的类型完全正确,否则方法将会遇到麻烦。方法被传递给它。与其让事情听天由命,不如通过修改 retrieve
的签名来锁定它。方法,使其变成这样:
public static <T, P> List<T> retrieve(Collection<T> args,
P value, Compare<T, P> c) {
现在是Compare
传递给 retrieve
的对象必须采用适用于 Collection<T>
的相同类型和 value
。完成此更改后,您可以内联 lambda 表达式,如下所示:
List<Point> matchingPoints = Utils.<Point, Integer>retrieve(
points, 0, (p, x) -> p.x == x);
您现在不会收到错误,因为严格类型应用于 Compare
retrieve
中的参数方法允许 IDE(和编译器)看到 lambda 的类型必须是 <Point, Integer>
.
关于java - 解析Java中的泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42213055/
我是一名优秀的程序员,十分优秀!