gpt4 book ai didi

java - 下界通配符 Java - 访问方法

转载 作者:搜寻专家 更新时间:2023-11-01 03:17:51 25 4
gpt4 key购买 nike

我知道存在下界通配符的原因之一是在添加新元素时集合不是不可变的。

例如

List<? extends Number> obj = new ArrayList<>();//Now this list is immutable
obj.add(new Integer(5));//Does not compile
List<? super Number> objTwo = new ArrayList<>();//This list is mutable
objTwo.add(new Integer(5));//Compiles

以下无法编译,因为我试图获取数字的长值。

Q1:我可以使用哪些方法?只有对象方法?:

public void testLowerBounds(List<? super Number> numbers){
if (!numbers.isEmpty()){
System.out.println(numbers.get(0).longValue());//Does not compile
}

我的问题是如何产生的:我目前正在学习流,书中指定了以下流方法:

Optional<T> min(Comparator<? super T> comparator)

并实现如下:

Stream<String> s = Stream.of("monkey", "ape", "bonobo");    
Optional<String> min = s.min((s1, s2) -> s1.length()—s2.length());

Q2:比较器在使用时如何允许使用字符串方法?

如果我必须回答问题 2:我会说 optional 指定“你必须向我传递一个 Comparator 的实现,它具有通用类型“String”或实现“String”的东西。我这样说是否正确?

期待您的回复。

最佳答案

首先,您不应将通配符类型参数与可变性混淆。在 List 中使用通配符的元素类型不会阻止修改,它只会对您可以对列表执行的操作施加一些实际限制。

有一个声明为 List<? extends Number> 的列表暗示引用列表的实际元素类型为 NumberNumber 的子类,例如它可能是 List<Integer>List<Double> .所以你不能随意添加 Number实例,因为您不知道它是否与实际元素类型兼容。

但您仍然可以添加 null , 作为 null已知引用与所有引用类型兼容。此外,您始终可以从列表中删除元素,例如调用removeclear没有什么问题。您还可以调用类似 Collections.swap(list, index1, index2) 的方法,这很有趣,因为调用 list.set(index1, list.get(index2)) 是不合法的由于关于通配符类型的正式规则,但是将列表传递给另一个可能使用非通配符类型变量来表示列表元素类型的方法是可行的。这显然是正确的,因为它只设置来自同一列表的元素,这些元素必须兼容。

同样,如果您有一个 Comparator<Number> ,您可以调用Collections.sort(list, comparator) ,作为可以处理任意数字的比较器,将能够处理列表中实际存储的任何数字。

总而言之,有 ? extends在集合的元素类型中不会阻止修改。


如前所述,您不能将任意新元素插入到实际元素类型可能是边界的未知子类的列表中,例如 List<? extends Number>。 .但你一定会得到 Number检索元素时的实例,作为 Number 子类型的每个实例也是 Number 的一个实例.当你声明一个 List<? super Number> , 它的实际元素类型可能是 NumberNumber 的父类(super class)型,例如ObjectSerializable .您可以插入任意 Number实例,如您所知,它将与列表具有的任何实际元素类型兼容,因为它是数字的父类(super class)型。当你检索一个实例时,你只知道它是Object的一个实例。 ,因为这是所有实例的父类(super class)型。与 ? extends 比较案例,有一个? super声明并不妨碍阅读,它只是强加了一些实际限制。同样,您仍然可以将其传递给 Collections.swap ,因为无论我们对实际类型知之甚少,插入我们刚从同一个列表中检索到的内容都是有效的。

在你的第二个问题中,你混淆了双方。您现在没有查看 min 的实现, 但在 caller 处。 min(Comparator<? super T> c)的声明允许调用者传递任何用 T 参数化的比较器或 T 的父类(super class)型.所以当你有一个 Stream<String> , 传递 Comparator<String> 是有效的到 min方法,这正是您通过 (s1, s2) -> s1.length()—s2.length() 实现的方法lambda 表达式(不过,我更喜欢 Comparator.comparingInt(String::length) )。

内执行 min ,确实也不知道什么,TComparator 的实际类型参数, 是。但是知道任何类型为 T 的流元素就足够了可以传递给比较器的 compare方法,可能需要 TT 的父类(super class)型.

关于java - 下界通配符 Java - 访问方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42051112/

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