gpt4 book ai didi

Java - Comparator类比较方法的定义

转载 作者:行者123 更新时间:2023-12-05 02:43:04 25 4
gpt4 key购买 nike

我想了解方法的定义 comparing比较器类。我会留下一些代码,以防它有助于解释。我正在使用一个名为 Person 的类,它基本上存储姓名和姓氏。可以使用 get 方法检索此数据。

public class Person {

private final String name;
private final String lastname;

public Person(String name, String lastname) {
this.name = name;
this.lastname = lastname;
}

public String getName() { return name; }

//...
}

然后我创建了一个人员列表:

List<Person> list = Arrays.asList(
new Person("Juan", "García"),
new Person("Ana", "Martínez"),
...
);

我一直在测试不同的方法来对这个 Persons 列表进行排序。在其他可能性中,我发现了这个:

list.sort(Comparator.comparing(Person::getName));

我明白这些行的作用。基本上,此列表使用比较器排序,该比较器使用排序键(人名)进行比较。使用对属于 Person 类的 getName 方法的引用来提取此类 key 。

不过,我也喜欢了解幕后发生的事情。我的问题是 comparing方法。 Java 文档定义了这样的方法:

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

特别是,我正在努力处理通用类型定义:<T,U extends Comparable<? super U>> ;以及参数类型的定义:Function<? super T,? extends U>

T代表比较器类型,而U代表 key 类型,对吧?所以……为什么U需要扩展 Comparable<? super U> ,它又使用 U 的任何父类(super class)?

在参数中,该函数使用属于 T 的任何父类(super class)的对象并返回属于 U 的任何子类的对象( <? super T,? extends U> ),但是……为什么呢?

我希望我的疑问是清楚的。另外,对于冗长的解释,我们深表歉意。

最佳答案

我在这里看到三个主要的混淆:

为什么 U extends Comparable<? super U>

这是对 U 的约束(键的类型),指定具体的类型U可。它说 U必须具有可比性。有道理,对吧?尖括号中的部分指定“U 可以比作什么?”例如,Comparable<Animal>意思是“比得上动物”。约束表示“U 必须与 U 的某些父类(super class)型相当”。

您可能想知道为什么它不直接说“U 必须与U 相当”,即U extends Comparable<U> .这是因为我们试图使我们的方法尽可能灵活,即我们尝试接受尽可能多的不同 U。尽可能。如果我有一个 Dog可以与 Animal 进行比较(实现 Comparable<Animal> ),这只狗也可以与另一只狗进行比较是合乎逻辑的 Dog .然而,由于 Dog工具 Comparable<Animal>而不是 Comparable<Dog> , 它不满足 U extends Comparable<U> ,这就是为什么我们必须使用 U extends Comparable<? extends U> .

为什么 Function? super T

假设我有一个提取 Object 的 key 提取器,然后我返回它的 toString()输出作为比较的关键(这是比较不常见的事情,但为了这个例子,请耐心等待 :D)

Function<Object, String> stringExtractor = Object::toString;

现在我想要一个比较动物的比较器。我可以用这个吗 stringExtractor作为 comparing 的参数?我当然可以:

Comparator<Animal> comparator = Comparator.comparing(stringExtractor);

所有动物都有一个toString方法,因为它们是 Object 的子类毕竟!这就是为什么关键提取器参数采用采用父类(super class) T 的函数的原因。 - 允许我们传递上述内容。如果是 Function<T, ? extends U> ,我们将无法做到 Comparator.comparing(stringExtractor) .

同样,我们想要 comparing处理尽可能多的事情。

为什么 Function返回 ? extends U

这其实是没有必要的。除非您明确指定 TU像这样:

Comparator.<Foo, Animal>comparing(Foo::getDog);

是否为Function<? super T, U>没有区别或 Function<? super T, ? extends U> .参见 this question更多细节。那个问题是关于 thenComparing ,其签名为 comparing .

关于Java - Comparator类比较方法的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67069621/

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