Thursday, August 25, 2016

The most common Stream operations

Streams represent one of the major revolutionary features of Java 8. In this article, you will see the most used operations grouped by type in brief.

1- Generating streams (Source):


Example:

Path path = Paths.get("file.txt");
String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
Stream<String> words = Stream.of(contents.split("[\\P{L}]+"));
Or
Stream<String> wordsAnotherWay = Pattern.compile("[\\P{L}]+").splitAsStream(contents);


Description:

Generate a stream of String containing the existing words within the file "file.txt".


Method's signature:

<String> Stream<String> java.util.stream.Stream.of(String... values)
Stream<String> java.util.regex.Pattern.splitAsStream(CharSequence arg0)

Example:

Stream<String> song = Stream.of("gently", "down", "the", "stream");

Description:

Generates stream of String containing the words passed as var-args argument.

Example:

Stream<String> silence = Stream.empty();
Or
silence = Stream.<String>empty(); // Explicit type specification

Description:

Generate an empty stream of String.

Method's signature:

<Object> Stream<Object> java.util.stream.Stream.empty()

Example:

Stream<String> echos = Stream.generate(() -> "Echo");

Description:

Generates an infinite stream of String containing the "Echo" values.

Method's signature:

<String> Stream<String> java.util.stream.Stream.generate(Supplier<String> s)

Example:

Stream<Double> randoms = Stream.generate(Math::random);

Description:

Generates an infinite stream of Double containing random values.

Method's signature:

<Double> Stream<Double> java.util.stream.Stream.generate(Supplier<Double> s)

Example:

Stream<BigInteger> integers = Stream.iterate(BigInteger.ONE, n -> n.add(BigInteger.ONE));

Description:

Generates an infinite stream of BigInteger containing values 1,2,3...

Method's signature:

<BigInteger> Stream<BigInteger> java.util.stream.Stream.iterate(BigInteger seed, UnaryOperator<BigInteger> f)


Example:

Path path = Paths.get("file.txt");
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {

}

Description:

Generates a stream of String containing lines within the file "file.txt".
As you could see here the generation of the stream is made within a try with resources block. Since Stream class implements AutoCloseable interface, the stream and the underlying resource (path in this case) will be closed automatically at the end of the try block.

Method's signature:

Stream<String> java.nio.file.Files.lines(Path path, Charset cs) throws IOException

Example:

Stream<String> words = wordList.stream();

Description:

Generates stream of String from worldList list

Method's signature:

Stream<String> java.util.Collection.stream()


Example:

Optional<String> optionalString = Optional.empty();

Description:

Genarates an empty optional.

Method's signature:

<Object> Optional<Object> java.util.Optional.empty()

Example:

Optional.of(Math.sqrt(x));

Description:

Generates an Optional<Double> containing the square root of (x is a double value).

Method's signature:

<Double> Optional<Double> java.util.Optional.of(Double value)

2- Intermediate operations:


Example:

Stream<String> longWords = words.filter(w -> w.length() > 10);

Description:

Filters worlds having more than 10 characters.

Method's signature:

Stream<String> java.util.stream.Stream.filter(Predicate<? super String> predicate)

Example:

Stream<String> lowercaseWords = words.map(String::toLowerCase);
Stream<String> noVowelsWords = words.map(s -> s.replaceAll("[aeiouAEIOU]", ""));

Description:

The first statement applies toLowerCase() method on each string within the stream words and returns a new stream stored into lowercaseWords stream. Whereas, the second statement replaces all vowels with an ampty string.

Method's signature:

<String> Stream<String> java.util.stream.Stream.map(Function<? super String, ? extends String> mapper)

Example:

Stream<Integer> notTheFirst = integers.skip(1);

Description:

This one does the opposite of limit(int) method; it excludes the first element of the Integer's stream integers.

Method's signature:

Stream<Integer> java.util.stream.Stream.skip(long n)

Example:

public static Stream<Character> characterStream(String s) {
List<Character> result = new ArrayList<>();
for (char c : s.toCharArray())
result.add(c);
return result.stream();
}

Stream<Character> combined = Stream.concat(characterStream("Hello"), characterStream("World"));

Description:

Concatenate two streams of Character. Note that concat() method available only for Character type.

Method's signature:

<Character> Stream<Character> java.util.stream.Stream.concat(Stream<? extends Character> a, Stream<? extends Character> b)

Example:

Stream<String> uniqueWords = Stream.of("merrily", "merrily", "merrily", "gently").distinct();

Description:

Generates a new stream of only distinct words.

Method's signature:

Stream<String> java.util.stream.Stream.distinct()

Example:

Stream<String> sorted = words.sorted();

Description:

Generates a new stream of sorted strings.

Method's signature:

Stream<String> java.util.stream.Stream.sorted()

Example:

Stream<String> longestFirst = words.sorted(Comparator.comparing(String::length).reversed());

Description:

Generates a stream of words sorted by length in descending order.

Method's signature:

Stream<String> java.util.stream.Stream.sorted(Comparator<? super String> comparator)

3- Terminal operations:


Example:

final int SIZE = 10;
List<String> firstElements = stream.limit(SIZE).collect(Collectors.toList());

Description:

Collect the first 10 elements of stream into firstElements list.

Method's signature:

<List<String>, ?> List<String> java.util.stream.Stream.collect(Collector<? super String, ?, List<String>> collector)

Example:

Object[] powers = Stream.iterate(1.0, p -> p * 2).peek(e -> System.out.println("Fetching " + e)).limit(20).toArray();

Description:

Generates a stream of Integer, picks the first 20 values as streams are evaluated lazily i.e. until the call of the terminal operation, print the selected values out, then, results in an array of objects stored into power variable.

Method's signature:

Object[] java.util.stream.Stream.toArray()

Example:

Optional<String> last = words.max(String::compareToIgnoreCase);
if (last.isPresent())
System.out.println("last: " + last.get());

Description:

Output an Optional of type String containing the last world lexicographically contained within the stream of strings words.

Method's signature:

Optional<String> java.util.stream.Stream.max(Comparator<? super String> comparator)

Example:

boolean aWordStartsWithQ = words.anyMatch(s -> s.startsWith("Q"));

Description:

Returns a boolean value representing wether there is or there is not any value starting with the letter "Q" within the stream words.

Method's signature:

boolean java.util.stream.Stream.anyMatch(Predicate<? super String> predicate)

Example:

Optional<String> startsWithQ = words.parallel().filter(s -> s.startsWith("Q")).findAny();

Description:

Returns an optional string containg any word starting with "Q" regardless of the values' order within the original stream.

Method's signature:

Optional<String> java.util.stream.Stream.findAny()

Example:

Optional<String> optionalValue = wordList.stream().filter(s -> s.contains("red")).findFirst();
optionalValue.ifPresent(s -> System.out.println(s + " contains red"));
Or
System.out.print(optionalValue.orElse("No word") + " contains red");
Or
optionalValue.orElseGet(() -> System.getProperty("user.dir"));
Or
try {
String result = optionalValue.orElseThrow(NoSuchElementException::new);
System.out.println("result: " + result);
} catch (Throwable t) {
t.printStackTrace();
}

Description:

Print out an optional string representing the first value within the original stream containing "red".

Method's signature:

Optional<String> java.util.stream.Stream.findFirst()


Example:

Optional<Integer> sum = values.reduce((x, y) -> x + y);
Or
Integer sum2 = values.reduce(0, (x, y) -> x + y);

Description:

Returns the sum of values contained within the stream of integers.

Method's signature:

Optional<Integer> java.util.stream.Stream.reduce(BinaryOperator<Integer> accumulator)
Integer java.util.stream.Stream.reduce(Integer identity, BinaryOperator<Integer> accumulator)

Example:

int result = words.reduce(0, (s, w) -> s + w.length(), (s1, s2) -> s1 + s2);

Description:

Counts the number of letters contained within the stream of words.

Method's signature:

<Integer> Integer java.util.stream.Stream.reduce(Integer identity, BiFunction<Integer, ? super String, Integer> accumulator, BinaryOperator<Integer> combiner)


Example:

System.out.println("[" + set.stream().limit(10).map(Object::toString).collect(Collectors.joining(", ")) + "]");

Description:

Prints out the first 10 element of the set separated by comma.

Method's signature:

<String, ?> String java.util.stream.Stream.collect(Collector<? super String, ?, String> collector)


Example:

Iterator<Integer> iter = Stream.iterate(0, n -> n + 1).limit(10).iterator();
while (iter.hasNext())

System.out.println(iter.next());

Description:

Result in an iterator containing the first ten iterarions of the original stram.

Method's signature:

Iterator<Integer> java.util.stream.BaseStream.iterator()


Example:

Integer[] numbers = Stream.iterate(0, n -> n + 1).limit(10).toArray(Integer[]::new);

Description:

Results in array of integers consisting of the first ten iterations of the original array.

Method's signature:

<Integer> Integer[] java.util.stream.Stream.toArray(IntFunction<Integer[]> generator)

Example:

HashSet<String> wordsHashSetwords.collect(HashSet::new, HashSet::add, HashSet::addAll);
Set<String> wordsSetwords.collect(Collectors.toSet());
TreeSet<String> wordsTreeSetwords.collect(Collectors.toCollection(TreeSet::new));

Description:

The previous statements represent three different ways to collect streams into sets.

Method's signature:

<HashSet<String>> HashSet<String> java.util.stream.Stream.collect(Supplier<HashSet<String>> supplier, BiConsumer<HashSet<String>, ? super String> accumulator, BiConsumer<HashSet<String>, HashSet<String>> combiner)
<Set<String>, ?> Set<String> java.util.stream.Stream.collect(Collector<? super String, ?, Set<String>> collector)
<TreeSet<String>, ?> TreeSet<String> java.util.stream.Stream.collect(Collector<? super String, ?, TreeSet<String>> collector)

Example:

IntSummaryStatistics summary = words.collect(Collectors.summarizingInt(String::length));
double averageWordLength = summary.getAverage();
double maxWordLength = summary.getMax();

Description:

Terminate the pipeline getting statistics about words' length.

Method's signature:

<IntSummaryStatistics, ?> IntSummaryStatistics java.util.stream.Stream.collect(Collector<? super String, ?, IntSummaryStatistics> collector)


Example:

Map<Integer, Person> idToPerson = people.collect(Collectors.toMap(Person::getId, Function.identity()));

Method's signature:

<Map<Integer, Person>, ?> Map<Integer, Person> java.util.stream.Stream.collect(Collector<? super Person, ?, Map<Integer, Person>> collector)


Example:

idToPerson = people
.collect(Collectors.toMap(Person::getId, Function.identity(), (existingValue, newValue) -> {
throw new IllegalStateException();
}, TreeMap::new));

Method's signature:

<TreeMap<Integer, Person>, ?> TreeMap<Integer, Person> java.util.stream.Stream.collect(Collector<? super Person, ?, TreeMap<Integer, Person>> collector)


Example:

Stream<Locale> locales = Stream.of(Locale.getAvailableLocales());
Map<String, String> languageNames = locales.collect(Collectors.toMap(Locale::getDisplayLanguage,
 Locale::getDisplayLanguage, (existingValue, newValue) -> existingValue));


Map<String, Set<String>> countryLanguageSets = locales.collect(Collectors.toMap(Locale::getDisplayCountry,
 l -> Collections.singleton(l.getDisplayLanguage()), (a, b) -> { // union of a and b
 Set<String> r = new HashSet<>(a);
 r.addAll(b);
 return r;
 }));


Method's signature:

<Map<String, Set<String>>, ?> Map<String, Set<String>> java.util.stream.Stream.collect(Collector<? super Locale, ?, Map<String, Set<String>>> collector)


No comments:

Post a Comment