java-8 - 将 Java8 流数组转换为元组流

标签 java-8 java-stream

假设我有一组 Java 8 流:Stream<T>[] streams ,我想创建一个流,其中新流的每个元素都是一个数组,通过从每个初始基本流中选择一个元素组成(假设它们都是连续的)。

例如,如果我有:

  streams [ 0 ] returning: ( "A", "B", "C" ), 
  streams [ 1 ] returning ( "X", "Y", "Z" ) 
  and streams [ 2 ] as ( "0", "1", "2" )

我想要一个返回的流
  ( { "A", "X", "0" }, { "B", "Y", "1" }, { "C", "Z", "2" } )

是否有一些代码已经实现了这一点?我知道如何去做,这将是 pair case 的概括。 ,但我想知道可重用的东西是否已经存在。

编辑 : 抱歉,我意识到我需要澄清一下:
  • 我不想创建整个矩阵,我想要一个每次动态返回一行的流(首先是 A/X/0,然后是 B/Y/1 等),而不必占用所有行的内存提前。我对基本流的大小做出合理的假设很好(例如,取最小值,一旦有没有更多元素要返回的流就停止)。
  • 我知道这可以通过首先将基本流转换为迭代器,然后创建一个新的迭代器来实现,其中 next() 从每个下划线迭代器中选择一个元素并返回一个新行。这就是我上面链接的配对示例所做的,我可以自己实现它,在这里我试图了解它是否已经在某个库中完成(我知道 JDK 没有这样的功能)。
  • 最佳答案

    首先,保留一系列流是一个非常糟糕的主意,因为它们不能重用,而且会使已经很复杂的可能解决方案变得复杂。

    不,这在普通 JDK 中是不可能的。没有zip功能,我们也没有 Tuples ,所以恐怕这是你能想到的最好的事情:

    Stream[] streams = Stream.of(
      Stream.of("A", "B", "C"),
      Stream.of("X", "Y", "Z"),
      Stream.of("0", "1", "2"))
        .toArray(Stream[]::new);
    
    String[][] arrays = Arrays.stream(streams)
      .map(s -> s.toArray(String[]::new))
      .toArray(String[][]::new);
    
    int minSize = Arrays.stream(arrays)
      .mapToInt(s -> s.length)
      .min().orElse(0);
    
    String[][] zipped = IntStream.range(0, minSize)
      .mapToObj(i -> Arrays.stream(arrays)
      .map(s -> s[i])
        .toArray(String[]::new))
      .toArray(String[][]::new);
    

    首先,我们需要将一个流数组转换为一个数组数组或任何我们可以多次遍历的东西。

    其次,如果数组内的流具有不同的长度,您没有指定要做什么,我假设标准 zip只要我们可以从每个集合中提取元素,就可以连接元素。

    第三,我在这里创建了一个包含所有可能索引的流,用于压缩 ( IntStream.range(0, minSize) ) 并从每个嵌套数组中逐个元素地手动提取元素。

    在这里在 Optional 上使用 .get() 很好,因为计算 minSize 保证那里会有一些东西。

    假设我们正在处理列表列表,这是一种更合理的方法:
    List<List<String>> lists = Arrays.asList(
      Arrays.asList("A", "B", "C"),
      Arrays.asList("X", "Y", "Z"),
      Arrays.asList("0", "1", "2"));
    
    final int minSize = lists.stream()
      .mapToInt(List::size)
      .min().orElse(0);
    
    List<List<String>> result = IntStream.range(0, minSize)
      .mapToObj(i -> lists.stream()
      .map(s -> s.get(i))
        .collect(Collectors.toList()))
      .collect(Collectors.toList());
    

    Java 9 的 Stream API 添加可能会让我们放弃计算 minSize .

    如果您希望序列的生成保持lazy ,您可以简单地不收集结果:
    IntStream.range(0, minSize)
      .mapToObj(i -> lists.stream()
        .map(s -> s.get(i))
        .collect(Collectors.toList()));
    

    关于java-8 - 将 Java8 流数组转换为元组流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45291750/

    相关文章:

    java - Java 8 中 throwingMerger 的替代方案

    Java 8流短路

    java - Java Collectors.groupingBy 是否可以将 Stream 作为其分组项目列表返回?

    java - Java有没有通过多次调用一个函数来填充一个List的方法?

    java - 该表达式的目标类型应该是函数接口(interface)

    Java 8 对泛型方法的调用不明确

    java - 如何重写 HttpServletRequest toString 方法?

    java - 使用 java8 功能计算列表中的元素数量

    Java 流 : use optional filter() operations on chaining

    java - 带比较器的流排序方法