使用Lambda函数来消耗供应商提供的所有对象

Sco*_*ttK 7 lambda consumer java-stream java-9 supplier

寻找如何使用Java lambda函数,以便Consumer可以处理供应商提供的所有对象,并摆脱显式while循环和null检查.

我有一个数据库的String键供应商,我想使用Consumer来处理每个键.

Supplier<String> keyGen = new SimpleKeySupplier(keyPrefix, numKeys);
Consumer<String> consumer = (String key) -> System.out.println("key="+key);
Run Code Online (Sandbox Code Playgroud)

我想consumer处理由提供的每个密钥,keyGen并尝试以下.它有效,但我确信必须有一种更简洁的方法来使用lambda函数来简化这一过程.

    // Test that the correct keys have been populated.
    Supplier<String> keyGen = new SimpleKeySupplier(keyPrefix, NumKeys);
    String k = keyGen.get();
    while(k != null) {
        consumer.accept(k);
        k = keyGen.get();
    }
Run Code Online (Sandbox Code Playgroud)

SimpleKeySupplier工作,简化版本如下:

import java.util.function.Supplier;

public class SimpleKeySupplier implements Supplier<String> {
    private final String keyPrefix;
    private final int numToGenerate;
    private       int numGenerated;

    public SimpleKeySupplier(String keyPrefix, int numRecs) {
        this.keyPrefix = keyPrefix;
        numToGenerate  = numRecs;
        numGenerated   = 0;
    }
    @Override
    public String get() {
        if (numGenerated >= numToGenerate) 
            return null; 
        else   
            return (keyPrefix + numGenerated++);
    }
}
Run Code Online (Sandbox Code Playgroud)

此示例中的Consumer大大简化了在StackOverflow上发布.

Rav*_*ala 7

您可以这样做,并在Java9中添加新功能.

Stream.generate(keyGen).takeWhile(Objects::nonNull).forEach(consumer);
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,"Stream.generate"产生一个*无序流*,这有助于进一步有效地使用`takeWhile`. (2认同)
  • @nullpointer实际上,它打破了操作.由于流是*无序*,当存在"null"元素时,它没有实际处理的元素数量的约束,因为它允许表现为 - 如果`null`处于任意位置(*无序)*意味着没有有意义的立场),包括第一个位置.它甚至可能尝试消耗"null"元素之后的元素,因为"before"和"after"在无序流中没有任何意义.你是对的,这将有助于在内部优化`takeWhile`,但不是OP想要的方式...... (2认同)
  • @ScottK"处理它们全部"对于无限流不是一个好主意.遇到`null`时,需要有序流才能正确终止,例如`Stream.iterate(supplier.get(),Objects :: nonNull,prev - > supplier.get()).......,但正如你所看到的,"供应商"并不是一个很好的起点.我已经在[本评论]中提供了更好的选择(/sf/ask/3769133231/?noredirect= 1个#comment94579576_53844760). (2认同)

Swe*_*per 5

你可以使用Stream:

Stream.generate(keyGen).limit(NumKeys).forEach(consumer);
Run Code Online (Sandbox Code Playgroud)

Stream.generate将创建一个持续呼叫get所提供的供应商的流.

limit使流有限,将其限制为x元素.在这种情况下,我可以看到keyGen只生成NumKeys密钥,所以我从那一点"切断"流.


Ton*_*hen 5

试试这个

Supplier<String> keyGen = new SimpleKeySupplier(keyPrefix, numKeys);
Consumer<String> consumer = (String key) -> System.out.println("key="+key);
Stream.generate(keyGen).filter(s -> s !=null).limit(NumKeys).forEach(consumer);
Run Code Online (Sandbox Code Playgroud)