Java - Comparator比较方法的定义class
Java - Definition of the comparing method of Comparator class
我想了解比较器class的方法comparing
的定义。我会留下一些代码,以防它有助于解释。我正在使用一个名为 Person 的 class,它基本上存储姓名和姓氏。可以使用 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 class.
的 getName 方法的引用来提取此类密钥
不过,我也很想了解幕后的情况。我的问题是 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
代表键类型,对吧?所以...为什么 U
需要扩展 Comparable<? super U>
,后者又使用 U
的任何 superclass?
在参数中,该函数使用属于 T
的任何 superclass 的对象和 returns 属于 [=] 的任何子 class 的对象21=] (<? super T,? extends U>
),但是……为什么?
我希望我的疑问是清楚的。另外,抱歉解释得太长了。
让我们考虑上述方法的签名 comparing
static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
T
是被比较对象的类型,在上述情况下是 Person
U extends <Comparable<? super U>>
描述了用于实现实际比较的类型 - 这就是为什么这种类型必须是 Comparable
- 在这种情况下它是 String
Function<? super T,? extends U> keyExtractor
- keyExtractor
是一个将 class T
(Person
) 的对象“转换”为可比较对象的函数class U
(String
) - 在此 class 中,它是 getter class Person
中定义的名称。
我在这里看到三个主要的困惑:
为什么 U extends Comparable<? super U>
?
这是对 U
(键的类型)的约束,指定了 U
可以是什么特定类型。它说 U
必须具有可比性。有道理,对吧?尖括号中的部分指定“U
可以比作什么?”例如,Comparable<Animal>
表示“堪比动物”。约束表示“U
必须与 U
的某些超类型相当”。
您可能想知道为什么它不直接说“U
必须与 U
相当”,即 U extends Comparable<U>
。这是因为我们试图使我们的方法尽可能灵活,即我们尝试接受尽可能多的不同 U
。如果我有一个可以与 Animal
(实现 Comparable<Animal>
)进行比较的 Dog
,那么狗也可以与另一个 Dog
进行比较是合乎逻辑的。然而,由于 Dog
实现了 Comparable<Animal>
而不是 Comparable<Dog>
,它不满足 U extends Comparable<U>
,这就是为什么我们必须使用 U extends Comparable<? extends U>
.
为什么 Function
需要 ? super T
?
假设我有一个密钥提取器,它接受一个 Object
,我 return 它的 toString()
输出作为要比较的密钥(这是一个非常不常见的比较,但是为了这个例子,请耐心等待 :D)
Function<Object, String> stringExtractor = Object::toString;
现在我想要一个比较动物的比较器。我可以使用这个 stringExtractor
作为 comparing
的参数吗?我当然可以:
Comparator<Animal> comparator = Comparator.comparing(stringExtractor);
所有动物都有toString
方法,毕竟它们是Object
的子类!这就是为什么关键提取器参数采用采用超类 T
的函数的原因 - 以允许我们传递上述内容。如果是Function<T, ? extends U>
,我们就做不到Comparator.comparing(stringExtractor)
.
同样,我们的想法是 comparing
处理尽可能多的东西。
为什么 Function
return ? extends U
?
这其实是没有必要的。除非你像这样明确指定 T
和 U
:
Comparator.<Foo, Animal>comparing(Foo::getDog);
Function<? super T, U>
和Function<? super T, ? extends U>
没有区别。有关详细信息,请参阅 。这个问题是关于 thenComparing
,它的签名是 comparing
.
我想了解比较器class的方法comparing
的定义。我会留下一些代码,以防它有助于解释。我正在使用一个名为 Person 的 class,它基本上存储姓名和姓氏。可以使用 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 class.
的 getName 方法的引用来提取此类密钥不过,我也很想了解幕后的情况。我的问题是 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
代表键类型,对吧?所以...为什么 U
需要扩展 Comparable<? super U>
,后者又使用 U
的任何 superclass?
在参数中,该函数使用属于 T
的任何 superclass 的对象和 returns 属于 [=] 的任何子 class 的对象21=] (<? super T,? extends U>
),但是……为什么?
我希望我的疑问是清楚的。另外,抱歉解释得太长了。
让我们考虑上述方法的签名 comparing
static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
T
是被比较对象的类型,在上述情况下是Person
U extends <Comparable<? super U>>
描述了用于实现实际比较的类型 - 这就是为什么这种类型必须是Comparable
- 在这种情况下它是String
Function<? super T,? extends U> keyExtractor
-keyExtractor
是一个将 classT
(Person
) 的对象“转换”为可比较对象的函数classU
(String
) - 在此 class 中,它是 getter classPerson
中定义的名称。
我在这里看到三个主要的困惑:
为什么 U extends Comparable<? super U>
?
这是对 U
(键的类型)的约束,指定了 U
可以是什么特定类型。它说 U
必须具有可比性。有道理,对吧?尖括号中的部分指定“U
可以比作什么?”例如,Comparable<Animal>
表示“堪比动物”。约束表示“U
必须与 U
的某些超类型相当”。
您可能想知道为什么它不直接说“U
必须与 U
相当”,即 U extends Comparable<U>
。这是因为我们试图使我们的方法尽可能灵活,即我们尝试接受尽可能多的不同 U
。如果我有一个可以与 Animal
(实现 Comparable<Animal>
)进行比较的 Dog
,那么狗也可以与另一个 Dog
进行比较是合乎逻辑的。然而,由于 Dog
实现了 Comparable<Animal>
而不是 Comparable<Dog>
,它不满足 U extends Comparable<U>
,这就是为什么我们必须使用 U extends Comparable<? extends U>
.
为什么 Function
需要 ? super T
?
假设我有一个密钥提取器,它接受一个 Object
,我 return 它的 toString()
输出作为要比较的密钥(这是一个非常不常见的比较,但是为了这个例子,请耐心等待 :D)
Function<Object, String> stringExtractor = Object::toString;
现在我想要一个比较动物的比较器。我可以使用这个 stringExtractor
作为 comparing
的参数吗?我当然可以:
Comparator<Animal> comparator = Comparator.comparing(stringExtractor);
所有动物都有toString
方法,毕竟它们是Object
的子类!这就是为什么关键提取器参数采用采用超类 T
的函数的原因 - 以允许我们传递上述内容。如果是Function<T, ? extends U>
,我们就做不到Comparator.comparing(stringExtractor)
.
同样,我们的想法是 comparing
处理尽可能多的东西。
为什么 Function
return ? extends U
?
这其实是没有必要的。除非你像这样明确指定 T
和 U
:
Comparator.<Foo, Animal>comparing(Foo::getDog);
Function<? super T, U>
和Function<? super T, ? extends U>
没有区别。有关详细信息,请参阅 thenComparing
,它的签名是 comparing
.