Using Lambda functions to Consume all objects provided by a Supplier

188 Views Asked by At

Looking for how to use Java lambda functions so Consumer can process all objects provided by a Supplier, and get rid of the explicit while loop and null checks.

I have a Supplier of String keys for a database and I want to use a Consumer to process each of those keys.

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

I want consumer to process each key supplied by keyGen and tried the following. It works but I am sure that there must be a more concise way of using lambda functions to make this simpler.

    // 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();
    }

SimpleKeySupplier works, and a simplified version is presented below:

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++);
    }
}

The Consumer in this example is greatly simplified for posting on StackOverflow.

3

There are 3 best solutions below

0
On BEST ANSWER

Try this

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);
1
On

You can use a Stream:

Stream.generate(keyGen).limit(NumKeys).forEach(consumer);

Stream.generate will create a stream that keeps calling get on the supplier provided.

limit makes the stream finite, limiting it to x elements. In this case, I can see that keyGen will only generate NumKeys keys, so I "cut off" the stream from that point.

6
On

You may do it like so, with the new capabilities added in Java9.

Stream.generate(keyGen).takeWhile(Objects::nonNull).forEach(consumer);