Java does not have a Char Stream, so when working with Strings and constructing a Stream of Characters, an option is to get a IntStream of code points using String.codePoints() method. So IntStream can be obtained as below:
public IntStream stringToIntStream(String in) { return in.codePoints(); }
It is a bit more involved to do the conversion other way around i.e. IntStreamToString. That can be done as follows:
public String intStreamToString(IntStream intStream) { return intStream.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString(); }
It is possible to find the first element of a Stream that matches a condition.
For this example, we will find the first Integer whose square is over 50000.
IntStream.iterate(1, i -> i + 1) // Generate an infinite stream 1,2,3,4... .filter(i -> (i*i) > 50000) // Filter to find elements where the square is >50000 .findFirst(); // Find the first filtered element
This expression will return an OptionalInt with the result.
Note that with an infinite Stream, Java will keep checking each element until it finds a result. With a finite Stream, if Java runs out of elements but still can't find a result, it returns an empty OptionalInt.
Method references make excellent self-documenting code, and using method references with Streams makes complicated processes simple to read and understand. Consider the following code:
public interface Ordered { default int getOrder(){ return 0; } } public interface Valued<V extends Ordered> { boolean hasPropertyTwo(); V getValue(); } public interface Thing<V extends Ordered> { boolean hasPropertyOne(); Valued<V> getValuedProperty(); } public <V extends Ordered> List<V> myMethod(List<Thing<V>> things) { List<V> results = new ArrayList<V>(); for (Thing<V> thing : things) { if (thing.hasPropertyOne()) { Valued<V> valued = thing.getValuedProperty(); if (valued != null && valued.hasPropertyTwo()){ V value = valued.getValue(); if (value != null){ results.add(value); } } } } results.sort((a, b)->{ return Integer.compare(a.getOrder(), b.getOrder()); }); return results; }
This last method rewritten using Streams and method references is much more legible and each step of the process is quickly and easily understood - it's not just shorter, it also shows at a glance which interfaces and classes are responsible for the code in each step:
public <V extends Ordered> List<V> myMethod(List<Thing<V>> things) { return things.stream() .filter(Thing::hasPropertyOne) .map(Thing::getValuedProperty) .filter(Objects::nonNull) .filter(Valued::hasPropertyTwo) .map(Valued::getValue) .filter(Objects::nonNull) .sorted(Comparator.comparing(Ordered::getOrder)) .collect(Collectors.toList()); }
You may need to convert a Stream emitting Optional to a Stream of values, emitting only values from existing Optional. (ie: without null value and not dealing with Optional.empty()).
Optional<String> op1 = Optional.empty(); Optional<String> op2 = Optional.of("Hello World"); List<String> result = Stream.of(op1, op2) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); System.out.println(result); //[Hello World]
Example : Get a Stream of 30 elements, containing 21st to 50th (inclusive) element of a collection.
final long n = 20L; // the number of elements to skip final long maxSize = 30L; // the number of elements the stream should be limited to final Stream<T> slice = collection.stream().skip(n).limit(maxSize);
Notes:
Learn All in Tamil © Designed & Developed By Tutor Joes | Privacy Policy | Terms & Conditions