Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java8中,如何将一个流简化为另一个流?_Java_Java 8_Java Stream - Fatal编程技术网

在Java8中,如何将一个流简化为另一个流?

在Java8中,如何将一个流简化为另一个流?,java,java-8,java-stream,Java,Java 8,Java Stream,作为一个例子,我想创建一个无限的十组流,如下所示: 0=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 1=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 2=[20, 21, 22, 23, 24, 25, 26, 27, 28, 29] ... // create a stream from 0 (inclusive) to 100 (exclusive) IntStream.iterate(0, i -> i+1).boxed().l

作为一个例子,我想创建一个无限的十组流,如下所示:

0=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2=[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
...
// create a stream from 0 (inclusive) to 100 (exclusive)
IntStream.iterate(0, i -> i+1).boxed().limit(100)

// slow down
.peek((i) -> {try {Thread.sleep(50);} catch (InterruptedException e) {}})

// group by tens
/* ugly: */.collect(Collectors.groupingBy(i -> i / 10)).entrySet()
/* not working: */ //.makeSequentialGroups(i -> i / 10)

// print to console
.forEach(System.out::println);  
我想使用一个Int的Inifinite流作为输入,然后对其进行分组。如果第一个流迭代10次,则生成的流应该只迭代一次

我正在工作但不是很优雅的代码如下所示:

0=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2=[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
...
// create a stream from 0 (inclusive) to 100 (exclusive)
IntStream.iterate(0, i -> i+1).boxed().limit(100)

// slow down
.peek((i) -> {try {Thread.sleep(50);} catch (InterruptedException e) {}})

// group by tens
/* ugly: */.collect(Collectors.groupingBy(i -> i / 10)).entrySet()
/* not working: */ //.makeSequentialGroups(i -> i / 10)

// print to console
.forEach(System.out::println);  

如何生成int流的组,而不必收集和重新流?(如果可能的话,即使不必使用拳击)

我怀疑是否有办法,因为你不能在没有收集的情况下从a映射,也不能在没有收集的情况下进行分组。您可以创建自己的流,但我怀疑您是否真的想走这条路

所以,虽然这不是一个答案,但如果你想节省一些时钟周期,我会选择这样的方式:

IntStream.range(0, 10)
          .boxed()
          .collect(Collectors.toMap(
              Function.identity(), 
              (x) -> IntStream.range(x * 10, x * 10 + 10)
          )) 

看起来,如果一个流基于另一个流,那么它总是必须具有完全相同的条目数

然而,我找到了一个解决问题的独特方法:我将消费者包装成一个“GroupingConsumer”。这将终止初始流,但仍可以无限执行

生成的代码被截断:

// create a stream from 0 (inclusive) to infinity!
IntStream.iterate(0, i -> i+1).boxed()

// slow down
.peek((i) -> {try {Thread.sleep(50);} catch (InterruptedException e) {}})

// terminate the stream of single items (ungrouped)
.forEach(

    // create a wrap-around
    GroupingConsumer.create(

        // define the grouping rule
        i -> i/10,

        // the wrapped consumer
        System.out::println
)); 
GroupingConsumer
类:

import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Forwards a group of items, whenever the grouping-key changes
 *
 * @param <K> the type of the grouping key
 * @param <T> the type of the single entries
 */
class GroupingConsumer<K, T> implements Consumer<K> {

    private Function<K, T> keyCalculator;
    private Consumer<Entry<T, List<K>>> consumer;

    Entry<T, List<K>> currentGroup;

    /**
     * Wraps your consumer, so that it will get groups of items instead of single items.
     * 
     * @param keyCalculator the "grouping by"
     * @param consumer your consumer, that will be called less frequently
     * @return the wrapped consumer
     */
    public static <K, T> GroupingConsumer<K,T> create(Function<K, T> keyCalculator, Consumer<Entry<T, List<K>>> consumer) {
        GroupingConsumer<K, T> groupingConsumer = new GroupingConsumer<K, T>();
        groupingConsumer.consumer = consumer;
        groupingConsumer.keyCalculator = keyCalculator;
        return groupingConsumer;
    }

    @Override
    public void accept(K nextValue) {
        T key = keyCalculator.apply(nextValue);

        boolean newGroupRequired = false;

        if (currentGroup == null)
            newGroupRequired = true;
        else if (!currentGroup.getKey().equals(key)) {
            newGroupRequired = true;
            consumer.accept(currentGroup);
        }

        if (newGroupRequired)
            currentGroup = new SimpleEntry<T, List<K>>(key, new ArrayList<K>());
        currentGroup.getValue().add(nextValue);
    }
}
import java.util.AbstractMap.SimpleEntry;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Map.Entry;
导入java.util.function.Consumer;
导入java.util.function.function;
/**
*每当分组键更改时,转发一组项目
*
*@param分组键的类型
*@param单个条目的类型
*/
类GroupingConsumer实现了Consumer{
专用函数键计算器;
私人消费者;
项目组;
/**
*包装您的消费者,使其获得多组商品,而不是单个商品。
* 
*@param键计算器“分组依据”
*@param consumer您的消费者,其呼叫频率将降低
*@返回包装好的消费者
*/
公共静态分组消费者创建(函数键计算器,消费者){
GroupingConsumer GroupingConsumer=新的GroupingConsumer();
groupingConsumer.consumer=消费者;
groupingConsumer.keyCalculator=keyCalculator;
退货分组消费者;
}
@凌驾
公共无效接受(K下一个值){
T key=keyCalculator.apply(下一个值);
布尔值newGroupRequired=false;
如果(currentGroup==null)
newGroupRequired=true;
如果(!currentGroup.getKey().equals(key))则为else{
newGroupRequired=true;
consumer.accept(当前组);
}
如果(需要新组)
currentGroup=new SimpleEntry(键,new ArrayList());
currentGroup.getValue().add(nextValue);
}
}

我的库中提供了这样的功能,称为:您可以根据提供的谓词将相邻元素收集到中间列表中。例如:

IntStreamEx.iterate(0, i -> i+1).boxed().limit(100)
    .peek((i) -> {try {Thread.sleep(50);} catch (InterruptedException e) {}})
    .groupRuns((a, b) -> a/10 == b/10)
    .forEach(System.out::println);

您可以将数组视为一个键类型为primitive
int
的映射,唯一的区别在于它不是通过
Map查找值。get(i)
您通过
myArray[i]
查找值。使用数组对数组进行分组也可以根据需要避免装箱。这里有一个解决方案,可以在没有装箱的情况下产生类似的结果

    int[][] results = IntStream.iterate(0, i -> i + 10)
            .limit(10)
            .mapToObj(i -> (int[]) IntStream.range(i, i + 10).toArray())
            .toArray(int[][]::new);

    System.out.println(Arrays.deepToString(results));

您不必创建另一个流,您可以使用
Set
@Bubletan中的
forEach
方法谢谢您的提示,我更新了我的问题,不再包含过时的
forEach
,谢谢您的回答。你的图书馆看起来很有用!