当前位置: 首页 > 面试题库 >

为什么迭代 不提供stream()和parallelStream()方法?

贲凌
2023-03-14
问题内容

我想知道为什么Iterable接口不提供stream()parallelStream()方法。考虑以下类别:

public class Hand implements Iterable<Card> {
    private final List<Card> list = new ArrayList<>();
    private final int capacity;

    //...

    @Override
    public Iterator<Card> iterator() {
        return list.iterator();
    }
}

它是 一手 牌的一种实现,因为您在玩交易纸牌游戏时可以手拿牌。

本质上,它包装了List<Card>,可确保最大容量并提供其他一些有用的功能。最好将其直接实现为List<Card>

现在,为了方便起见,我认为实现起来会很不错Iterable<Card>,这样,如果您想对其进行循环,则可以使用增强的for循环。(我的Hand课程也提供了一种get(intindex)方法,因此Iterable<Card>我认为该方法是合理的。)

Iterable界面提供了以下内容(省略了javadoc):

public interface Iterable<T> {
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

现在您可以通过以下方式获取流:

Stream<Hand> stream = StreamSupport.stream(hand.spliterator(), false);

因此,真正的问题是:

  • 为什么不Iterable<T>提供实现stream()和的默认方法parallelStream(),我什么也看不到,因此不可能或不需要?

问题答案:

这不是遗漏;2013年6月在EG清单上进行了详细讨论。

专家组的确切讨论源于此主题。

尽管似乎“显而易见”(即使是对专家组stream()来说也是如此)似乎很有意义Iterable,但Iterable如此普遍的事实却成为一个问题,因为显而易见的签名是:

Stream<T> stream()

并非总是您想要的。例如,有些Iterable<Integer>本来希望其流方法返回的东西IntStream。但是,将这种stream()方法放在层次结构中的较高位置将使其无法实现。因此,相反,我们把它很容易使一个StreamIterable,通过提供一个spliterator()方法。stream()in
的实现Collection只是:

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

任何客户都可以通过以下方式从中获得所需的流Iterable

Stream s = StreamSupport.stream(iter.spliterator(), false);

最后,我们的结论是,加入stream()Iterable将是一个错误。



 类似资料:
  • 本质上,它包装了,确保了最大容量,并提供了一些其他有用的特性。更好的方法是直接将其实现为。 现在,为了方便起见,我认为最好实现,这样,如果您想要循环它,就可以使用增强的for-loops。(我的类还提供了方法,因此我认为是合理的。) 接口提供以下功能(省略了javadoc): null

  • 问题内容: 有人知道为什么JUnit 4提供但不提供方法吗? 它提供了(对应于)和(对应于),因此它们似乎没有包含在内就显得很奇怪。 顺便说一下,我知道JUnit插件提供了我正在寻找的方法。我只是出于好奇而问。 问题答案: 我建议您使用较新的样式断言,该断言可以轻松描述各种否定形式,并在断言失败时自动构建对您的期望和得到的结果的描述: 这三个选项都是等效的,请选择最容易阅读的一个。 要使用方法的简

  • 我很想知道为什么Java的可选不提供类似于流的方法。 接口的method javadoc声明: @apiNote此方法主要用于支持调试,您希望在元素流经管道中的某个点时看到这些元素 这几乎完全描述了我的用例: (返回 方法,上述所有内容都会转换为: 也可以这样做(参见此答案): 并将其与方法一起使用: 但我认为这是一个黑客,而不是的干净用法。 从Java 9开始,可以将< code>Optiona

  • 问题内容: 在Java 5及更高版本中,您具有foreach循环,该循环可以神奇地实现任何实现的对象: 但是,仍然没有实现,这意味着要迭代一个,您必须执行以下操作: 有谁知道为什么仍然不执行? 编辑: 为澄清起见,我不是在谈论枚举的语言概念,而是在Java API中称为“ 枚举 ” 的Java特定类。 问题答案: 枚举没有被修改为支持Iterable,因为它是一个接口,而不是一个具体的类(例如Ve

  • 问题内容: 为什么接口不扩展? 该方法可以简单地返回。 是故意的还是对Java设计师的监督? 能够将循环与这样的迭代器一起使用将很方便: 其中返回迭代器。 问题答案: 因为迭代器通常指向集合中的单个实例。Iterable意味着可以从一个对象获得迭代器以遍历其元素-无需迭代单个实例(迭代器代表的是该实例)。

  • 问题内容: 查看Guava的ImmutableList(和其他一些类),您会发现很多重载的便捷方法(“按顺序返回包含给定元素的不可变列表”。)这些方法使用不同数量的参数: 一直到这一步: 我的一些同事认为这很愚蠢,想知道为什么不只有一种方法:。他们怀疑这是不正确的性能“优化”,属于“您认为自己比编译器更聪明”之类的东西。 我的直觉是Kevin Bourrillion等。出于真正的原因将这些方法放在