gpt4 book ai didi

java - 解析Java中的泛型函数

转载 作者:行者123 更新时间:2023-11-30 02:39:24 24 4
gpt4 key购买 nike

所以我有这段代码,它使用多个映射来存储一些简单的类。现在我还想根据该项目的 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中有两个错误:

  1. 在 Utils.retrieve 中,eclipse 指出: Utils 类型中的方法retrieve(Collection, P, Compare) 不适用于参数 (Collection, int, (Point p, Integer x) -> {})
  2. 在 lambda 表达式中,Eclipse 指出:非法 lambda 表达式:Compare 类型的方法 apply 为

遇到这种情况该如何处理?提前致谢。

最佳答案

您已经非常接近获得所需的代码了。

首先,将通用参数声明移至接口(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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com