我正在尝试实现一个返回给定Comparable(通用)列表的最大对象的函数。
我有3个类,我已经实现了他们的compareTo方法,如果它比其他大,则返回1,如果小于其他,则返回-1,如果它们相等,则返回0。
现在我的问题是了解如何使用通用输入COmparable列表。
这是我的函数的签名,以及我到目前为止编写的代码(拒绝对我有用):
public static Comparable<?> getMax(List<Comparable<?>> ls) {
LinkedList<Comparable<?>> tmpComp = new LinkedList<Comparable<?>>();
for (Comparable<?> c : ls)
tmpComp.add(c);
Comparable<?> maxObj = tmpComp.get(0);
for (Comparable<?> c : tmpComp)
if (c.compareTo(maxObj) > 0)
m = c;
return m;
}
我正在编写一个包含用户的系统和广告。用户和广告这两个在我们的compareTo方法中都有“利润”字段的类就是比较两者中的哪一个(这个或其他)有更多的利润,然后根据它返回正确的值。第三个类通过另一个字段进行比较,该字段也是一个int,表示Quest的级别(int)。
此外,if语句特别为我提供了“不适用于参数”类型的错误。
任何线索?
提前致谢!
答案 0 :(得分:1)
阅读你的评论,我建议你重新设计你的模型:
interface ProfitGenerating {
double getProfit();
}
class User implements ProfitGenerating {
...
}
class Advert implements ProfitGenerating {
...
}
List<ProfitGenerating> profits = ...;
Optional<ProfitGenerating> maxProfit = profits.stream()
.max(Comparator.comparingDouble(ProfitGenerating::getProfit));
答案 1 :(得分:0)
MạnhQuyếtNguyễn的答案很好。但它没有考虑到你有多种潜在类型T的情况,这似乎是你的情况。
所以在那种情况下,只需用一个类包装你的各个类并使用他的解决方案。
如果你有一个User类和一个Ad类,那么创建一个这样的包装器:
class ProfitMaker implements Comparable<ProfitMaker> {
User user;
Ad ad;
public int compare(ProfitMaker p) {
//check my profit and compare with profit of p
}
}
将该课程用作&#34; T&#34;当使用来自MạnhQuyếtNguyễn的getMax时。
或者,使用界面
interface ProfitMaker extends Comparable<ProfitMaker> {
int getProfit();
}
让您的用户和广告类都实现该界面,并将该界面用作&#34; T&#34;以及来自MạnhQuyếtNguyễn的getMax方法。
答案 2 :(得分:0)
你的三个班级必须相互比较。为此,他们需要实现Comparable<SomeX>
,其中SomeX
是他们最低的共同超类。在最糟糕的情况下,SomeX
为Object
。
如果是这种情况,您只需执行以下操作:
ls.stream().max(Comparator.naturalOrder())
或者,您可以捕获Comparable<...>
中的比较语义,然后执行:
Comparator<...>
。
ls.stream().max(comparator)
对于类型不是真正“自然”的订单或可能存在不同订单的情况,使用比较器会更好。我认为这就是这种情况,因为您实际上比较了不同类型的实例。很难说某些命令对于这些实例来说是“自然的”,因为它们甚至不属于一种类型。
如果您根据他们共享的某些属性(例如int getProfit()
)比较您的实例,那么创建一个像Profitable
这样的公共界面是有意义的。然后你可以这样做:
ls.stream().max(Comparator.comparintInt(Profitable::getProfit))
请注意,如果您对私有类型进行比较,则应使用comparingInt
/ comparingLong
/ comparingDouble
代替comparing
,以避免不必要的装箱和拆箱。
如果由于某种原因无法创建和实现Profitable
等常用界面,您仍然可以使用comparingInt
并喜欢。你只会有一个更丑陋的lambda:
ls.stream().max(Comparator.comparintInt(l -> {
if (l instanceof Ad) { return ((Ad) l).getProfit(); }
else if (l instanceof Ransom) { return ((Ransom) l).getProfit(); }
// ...
else { throw new IllegalArgumentException(...); }
}))