当前位置: 首页 > 知识库问答 >
问题:

为什么许多Java流接口方法在参数中使用下界通配符而不是泛型类型?

萧萧迟
2023-03-14

许多Java流接口方法在参数中使用下界通配符

例如

Stream<T> filter(Predicate<? super T> pred)

void forEach(Consumer<? super T> action)

使用谓词有什么好处

我明白,用谓语


共有1个答案

韩明德
2023-03-14

我假设您知道PECS模式,这在设计应用编程接口时是有用的,即使没有实际的用例跳到您的眼睛里。当我们看到Java的最终状态

Stream.of("a", "b", "c").filter(Predicate.isEqual("b"));

需要过滤器(谓词

我们可能会认为Stream API的开发和新的Java语言版本/编译器实现是同时发生的,所以一开始使用PECS模式可能有一个实际的原因,而从来没有一个原因不要使用那种模式。它仍然提高了重用现有谓词、函数或消费者实例的灵活性,即使这可能不太常见,也没什么坏处。

注意,虽然,例如Stream.of(10,12.5). filter(n-

Predicate<Number> name = n -> n.doubleValue()>=10;
Stream.of(10, 12.5).filter(name);

只有当filter被声明为filter(谓词)时,才有效

Predicate<Number> name = n -> n.doubleValue()>=10;
Stream.<Number>of(10, 12.5).filter(name);

这已经说明了如何省略过滤器声明中的super可能会导致调用方更加冗长。此外,如果在以后的管道阶段需要更具体的元素类型,则强制使用更通用的元素类型可能不是一个选项。

虽然现有的函数实现很少,但也有一些,例如。

Stream.Builder<Number> b = Stream.builder();
IntStream.range(0, 10).boxed().forEach(b);
LongStream.range(0, 10).boxed().forEach(b);
Stream<Number> s = b.build();

没有<代码>就不能工作?superforEach(消费者)中

您可能更经常遇到的一种情况是,有一个现有的比较器实现,您可能希望将其传递给具有更具体元素类型的流的排序方法,例如,

Stream.of("FOO", "bar", "Baz")
      .sorted(Collator.getInstance())
      .forEachOrdered(System.out::println);

没有<代码>就不能工作?super排序(比较器)中

 类似资料:
  • 问题内容: 我知道Java的泛型类型有各种各样的违反直觉的属性。特别是我不理解的一个,希望有人可以向我解释。为类或接口指定类型参数时,可以对其进行绑定,以使其必须使用来实现多个接口。但是,如果要实例化实际对象,则此方法不再起作用。很好,但是无法编译。考虑以下完整代码段: 似乎应该明确定义的语义-我想通过允许两种类型(而不只是一种类型)的交集,不会损失类型安全性。我敢肯定有一个解释。有谁知道它是什么

  • 这是我试图理解的编译器行为的一个过度简化版本: 在上面的代码片段中,是一个类型范围比HouseCat接口允许的类型范围更广的引用,即: 如果我尝试执行类似的操作,编译器会告诉我不满足类型参数的约束。那么,,至少是潜在的。 编译器不会让我创建违反类型参数约束的实例,但我对它使用作为引用上限的行为感到困惑。在(,)之间有一个无效的类型范围,那么编译器为什么不拒绝这个引用定义呢? 澄清:我的问题不是关于

  • 我找不到更好的描述我的问题的主题,所以我会尝试更好地解释我的问题。我注意到,如果我使用有界通配符,我可以使用它的“bound”作为参数,但不能作为返回值。这可能听起来很混乱,所以我将直接粘贴我的代码。 我想知道为什么最后一行代码不能编译。当我显式地说的返回类型是<时,这个问题是什么?extends Object>。很明显String是一个对象。有人能帮我把这事弄清楚吗?

  • 在了解Java泛型的过程中,我遇到了以下问题: 假设我有下面的方法来添加列表的元素,只限于包含数字的列表。 但是这段代码和这段代码有什么不同: 它们都按预期编译和执行。这两者之间有什么区别?除了语法之外?什么时候我更喜欢使用通配符而不是前者? 是的,使用通配符方法,我不能在列表中添加除null之外的新元素,否则它将无法编译。除此之外呢?

  • null 为什么我不能在MyList中添加对象。因为如果我们使用super,这意味着这个列表可以包含在Java类的继承制度中等于或高于number的对象。因此应该按照该语句在列表中添加新的Object()。 多谢了。

  • 问题内容: 我正在刷新有关Java泛型的知识。因此,我转向了Oracle的优秀教程……并开始为我的同事编写一个演示文稿。我在本教程中遇到了有关通配符的部分,内容为: 考虑以下方法,printList: printList的目标是打印任何类型的列表,但未能实现该目标- 它仅打印Object实例的列表;它不能打印,,,等等,因为它们不是的亚型。要编写通用的printList方法,请使用: 我知道那是行