对于可能需要同时在多个边/对象上进行比较的情况,是否有任何标准接口或方法可用于集合/流(最大值,排序)?
签名可能类似于
compare(T... toCompare)
而不是
compare(T object1, T object2)
我想要的是一个用于比较Java API中的操作的实现。但从我看到的情况来看,我认为我必须强制要求单一的比较。
更新:实际示例:我希望通过Collections / Stream.max()解释比较器实现,这允许我进行多边比较而不是单一比较(即,在比较方法中接受多个T) 。 max函数返回元素,以便元素是比较机制的赢家,自定义实现,与所有其他元素相比,而不是n战1和1的胜者。
UPDATE2:更具体的例子: 我有(Pineapple,Pizza,Yogurt),并且max返回项目,这样我的自定义1 - > n比较返回最大商数。这个商可能像degreeOfYumie。所以菠萝比比萨饼+酸奶更像是yummie,比菠萝+酸奶更像是yummie,而Yogurt与Pizza + Pineapple同样是yummie。所以获胜者是Pineaple。如果我做那个单一的,所有的成分将同样yummie。是否有任何实施比较器的机制/可比较的?也许是一个"可排序的"适用于集合,流和队列的接口?
答案 0 :(得分:2)
不需要专门的interface
。如果您的Comparator
符合规范,则它将是可传递的并允许比较多个对象。要获得三个或更多元素的最大值,只需使用,例如
Stream.of(42, 8, 17).max(Comparator.naturalOrder())
.ifPresent(System.out::println);
// or
Stream.of("foo", "BAR", "Baz").max(String::compareToIgnoreCase)
.ifPresent(System.out::println);
如果您对max元素的索引感兴趣,可以这样做:
List<String> list=Arrays.asList("foo", "BAR", "z", "Baz");
int index=IntStream.range(0, list.size()).boxed()
.max(Comparator.comparing(list::get, String.CASE_INSENSITIVE_ORDER))
.orElseThrow(()->new IllegalStateException("empty list"));
关于您更新的问题...... 您说您希望根据元素属性和其余元素的商来建立排序。让我们通过
来思考假设我们有正数值a
,b
和c
,并希望根据a/(b+c)
,b/(a+c)
和{{1}建立排序}}
然后我们可以通过扩展商来改变这个词,使其具有一个共同点:
c/(a+b)
由于共同标准对订购没有影响,我们可以忽略它们,在扩展产品后我们得到了条款:
a(a+c)(a+b) b(b+c)(b+a) c(c+b)(c+a)
--------------- --------------- ---------------
(a+b)(b+c)(a+c) (a+b)(b+c)(a+c) (a+b)(b+c)(a+c)
在这里我们可以忽略共同的加法a³+a²b+a²c+abc b³+b²a+b²c+abc c³+c²a+c²b+abc
,因为它对排序没有影响。
abc
然后再次考虑
a³+a²b+a²c b³+b²a+b²c c³+c²a+c²b
看到我们有一个可以忽略的共同因素,因为它不会影响排序,所以我们最终得到
a²(a+b+c) b²(a+b+c) c²(a+b+c)
这个结果告诉我们什么?只是商数与a² b² c²
,a
和b
成比例,因此具有相同的排序。因此,当我们能够证明它与基于原始值c
,a
和b
的简单比较器具有相同结果时,不需要实现基于商的比较器。
(如果允许负值,图片会有所不同,但由于允许负值会产生零作为分母的可能性,无论如何它们都不在这个用例中)
应该强调的是,特定比较器的任何其他结果都将证明该比较器不适用于标准c
用例。如果所有其他元素的组合值对结果顺序产生影响,换句话说,向关系添加另一个元素将改变排序,如何将操作添加到Comparator
或将其插入到排序列表的正确位置有效吗?
答案 1 :(得分:1)
一次比较多个对象的问题是返回什么。 如果第一个对象“小于第二个对象,那么Java比较器返回-1;如果它们是等于,则返回0;如果第一个对象是”更大“,则返回1。
如果比较两个以上的对象,则整数不足以描述所述对象之间的差异。
答案 2 :(得分:1)
如果你有一个正常的Comparable<T>
,你可以按照你想要的方式组合它。从能够比较两件事你可以构建任何东西(参见不同的排序算法,通常只需要<
实现)。
例如,这里有一个天真的&#34;你可以说它是否比任何一个对象更大,相等或更小&#34;
<T extends Comparable<T>> int compare(T... toCompare) {
if (toCompare.length < 2) throw Nothing to compare; // or return something
T first = toCompare[0];
int smallerCount;
int equalCount;
int biggerCount;
for(int i = 1, n = toCompare.length; i < n; ++i) {
int compare = first.compareTo(toCompare[i]);
if(compare == 0) {
equalCount++;
} else if(compare < 0) {
smallerCount++;
} else {
biggerCount++;
}
}
return someCombinationOf(smallerCount, equalCount, biggerCount);
}
但是我无法找到合适的方法,(3, 5, 3, 1)
小于3
的序列5
,等于3
并且大于1
,因此所有计数均为1
;在这里你所有的&#34;它比任何&#34;更大,相等或更小。条件同时为真,但如果有助于将计数组合推迟到以后的某个时间点,则可以将计数作为对象返回。