多对象Comparable/Comparator 接口
Multiobject Comparable/Comparator interface
对于可能需要同时比较多个 sides/objects 的情况,collections/streams(最大值,排序)中是否有可用的标准接口或方法?
签名可能类似于
compare(T... toCompare)
而不是
compare(T object1, T object2)
我想要的是做一个用于比较 Java API 中的操作的实现。但据我所见,我认为我必须坚持强制比较。
更新:实际示例:我希望有一个由 Collections/Stream.max() 解释的 Comparator 实现,它允许我进行多边比较而不是单一比较(即在比较中接受多个 T方法)。 max 函数 returns 元素,因此该元素是比较机制的赢家,自定义实现,它与所有其他人相比,而不是 n 场战斗 1 对 1 的赢家。
更新 2:更具体的例子:
我有(菠萝、披萨、酸奶)和最大 returns 项,这样我的自定义 1 -> n 比较 returns 最大商。这个商数可能类似于 degreeOfYumie。所以菠萝比披萨+酸奶更美味,比萨比菠萝+酸奶更美味,酸奶比披萨+菠萝同样美味。所以赢家是菠萝。如果我做那个单一的,所有的成分都会同样美味。是否有任何机制可以像那样实现 comparator/comparable ?也许 "sortable" 接口适用于集合、流和队列?
一次比较多个对象的问题是return。
Java 比较器 returns -1 如果第一个对象 "smaller than the second one, 0 if they are equals and 1 if the first one is the " 更大”。
如果您比较两个以上的对象,一个整数不足以描述这些对象之间的差异。
如果你有一个普通的Comparable<T>
,你可以随意组合它。通过比较两件事,你可以构建任何东西(参见不同的排序算法,通常只需要 <
实现)。
例如,这是 "you could say if it's bigger, equal or smaller than ANY of the objects"
的一个天真的例子
<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
;这里所有 "it's bigger, equal or smaller than ANY" 条件同时为真,但是如果有助于将计数组合推迟到稍后的时间点,您可以 return 将计数作为一个对象。
不需要专门的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)
和 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
.[= 的简单比较器具有相同结果时,就没有必要实施基于商的比较器了。 34=]
(如果允许负值,情况会有所不同,但由于允许负值会产生将零作为分母的可能性,因此无论如何它们都不在这个用例中)
应该强调的是,特定比较器的任何其他结果都将证明该比较器无法用于标准 Comparator
用例。如果所有其他元素的组合值对结果顺序有影响,换句话说,向关系中添加另一个元素会改变顺序,那么将元素添加到 TreeSet
或将其插入到排序列表的正确位置有效吗?
对于可能需要同时比较多个 sides/objects 的情况,collections/streams(最大值,排序)中是否有可用的标准接口或方法?
签名可能类似于
compare(T... toCompare)
而不是
compare(T object1, T object2)
我想要的是做一个用于比较 Java API 中的操作的实现。但据我所见,我认为我必须坚持强制比较。
更新:实际示例:我希望有一个由 Collections/Stream.max() 解释的 Comparator 实现,它允许我进行多边比较而不是单一比较(即在比较中接受多个 T方法)。 max 函数 returns 元素,因此该元素是比较机制的赢家,自定义实现,它与所有其他人相比,而不是 n 场战斗 1 对 1 的赢家。
更新 2:更具体的例子: 我有(菠萝、披萨、酸奶)和最大 returns 项,这样我的自定义 1 -> n 比较 returns 最大商。这个商数可能类似于 degreeOfYumie。所以菠萝比披萨+酸奶更美味,比萨比菠萝+酸奶更美味,酸奶比披萨+菠萝同样美味。所以赢家是菠萝。如果我做那个单一的,所有的成分都会同样美味。是否有任何机制可以像那样实现 comparator/comparable ?也许 "sortable" 接口适用于集合、流和队列?
一次比较多个对象的问题是return。 Java 比较器 returns -1 如果第一个对象 "smaller than the second one, 0 if they are equals and 1 if the first one is the " 更大”。
如果您比较两个以上的对象,一个整数不足以描述这些对象之间的差异。
如果你有一个普通的Comparable<T>
,你可以随意组合它。通过比较两件事,你可以构建任何东西(参见不同的排序算法,通常只需要 <
实现)。
例如,这是 "you could say if it's bigger, equal or smaller than ANY of the objects"
的一个天真的例子<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
;这里所有 "it's bigger, equal or smaller than ANY" 条件同时为真,但是如果有助于将计数组合推迟到稍后的时间点,您可以 return 将计数作为一个对象。
不需要专门的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)
和 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
.[= 的简单比较器具有相同结果时,就没有必要实施基于商的比较器了。 34=]
(如果允许负值,情况会有所不同,但由于允许负值会产生将零作为分母的可能性,因此无论如何它们都不在这个用例中)
应该强调的是,特定比较器的任何其他结果都将证明该比较器无法用于标准 Comparator
用例。如果所有其他元素的组合值对结果顺序有影响,换句话说,向关系中添加另一个元素会改变顺序,那么将元素添加到 TreeSet
或将其插入到排序列表的正确位置有效吗?