StreamEx , IntStreamEx , LongStreamEx and DoubleStreamEx . To save the original interface, I had to write quite a few boring methods like the following: public class IntStreamEx implements IntStream { private final IntStream stream; @Override public <U> StreamEx<U> mapToObj(IntFunction<? extends U> mapper) { return new StreamEx<>(stream.mapToObj(mapper)); } ... } IntStreamEx.of(random) method). But then flows appeared that I can expand as I see fit. Below is a brief overview of the additional functionality..collect(Collectors.toSet()) or .collect(Collectors.toList()) . It looks verbose, even if you import the Collectors statically. In StreamEx I added methods toSet , toList , toCollection , toMap , groupingBy with several signatures. The toMap can toMap function for keys if it is identity. A couple of examples: List<User> users; public List<String> getUserNames() { return StreamEx.of(users).map(User::getName).toList(); } public Map<Role, List<User>> getUsersByRole() { return StreamEx.of(users).groupingBy(User::getRole); } public Map<String, Integer> calcStringLengths(Collection<String> strings) { return StreamEx.of(strings).toMap(String::length); } joining methods also correspond to collectors, but before that the contents of the stream are passed through String::valueOf : public String join(List<Integer> numbers) { return StreamEx.of(numbers).joining("; "); } .filter(obj -> obj instanceof MyClass) . However, this does not specify the type of stream, so you have to either manually type the elements or add one more step. .map(obj -> (MyClass)obj) . When using StreamEx this is done concisely using the select method: public List<Element> elementsOf(NodeList nodeList) { return IntStreamEx.range(0, nodeList.getLength()).mapToObj(nodeList::item).select(Element.class).toList(); } select method, by the way, the map step is not used, but simply after filtering, an unsafe stream type conversion is used, so the pipeline does not lengthen once again.nonNull() method to replace filter(Objects::nonNull) . There is also a remove(Predicate) method that removes elements from the stream that satisfy the predicate ( filter backwards). It allows more frequent use of references to methods: public List<String> readNonEmptyLines(Reader reader) { return StreamEx.ofLines(reader).map(String::trim).remove(String::isEmpty).toList(); } findAny(Predicate) and findFirst(Predicate) - shortcuts for filter(Predicate).findAny() and filter(Predicate).findFirst() . The has method allows you to find out if there is a specific element in the stream. Similar methods are added to primitive streams.Stream.concat not very nice, as it adds nested brackets and spoils the idea of reading the program from left to right. To replace concat I made append and prepend , which allow you to add another stream or a given set of values to the end or beginning of the current thread: public List<String> getDropDownOptions() { return StreamEx.of(users).map(User::getName).prepend("(none)").toList(); } public int[] addValue(int[] arr, int value) { return IntStreamEx.of(arr).append(value).toArray(); } Comparator.comparingInt . To reduce the most common situations of sorting, searching for the maximum and minimum by one key, the family of methods sortingBy , maxBy and minBy : public User getMostActiveUser() { return StreamEx.of(users).maxByLong(User::getNumberOfPosts).orElse(null); } Stream implement the Iterable interface, because it contains an iterator() method. This is not done, in particular, because Iterable implies reusability, and the iterator can only be taken once from the stream. Although the Stack Overflow noted that the JDK already has an exception to this rule - DirectoryStream . Anyway, sometimes you want to use the usual for loop instead of the terminal forEach . This gives a number of advantages: you can use any variables, not only effectively final, you can throw any exceptions, it is easier to debug, shorter than the spectra, etc. In general, I think that there is no big sin if you created the stream and immediately use its in for loop. Of course, care must be taken not to pass it on to methods that take Iterable and can bypass it several times. Example: public void copyNonEmptyLines(Reader reader, Writer writer) throws IOException { for(String line : StreamEx.ofLines(reader).remove(String::isEmpty)) { writer.write(line); writer.write(System.lineSeparator()); } } Map keys whose values satisfy a given condition, or vice versa. To write this directly is somewhat sad: you have to mess with Map.Entry . I hid it under the hood of the static methods ofKeys(map, valuePredicate) and ofValues(map, keyPredicate) : Map<String, Role> nameToRole; public Set<String> getEnabledRoleNames() { return StreamEx.ofKeys(nameToRole, Role::isEnabled).toSet(); } Map processing scenarios, a separate EntryStream class has been EntryStream - Map.Entry object Map.Entry . It partially repeats the functionality of StreamEx , but also contains additional methods that allow processing keys and values separately. In some cases, this makes it easier to both generate a new Map and disassemble an existing Map . For example, you can invert Map-List like this (strings from lists of values fall into keys, and keys form new lists of values): public Map<String, List<String>> invert(Map<String, List<String>> map) { return EntryStream.of(map).flatMapValues(List::stream).invert().grouping(); } flatMapValues , which turns the stream Entry<String, List> Entry<String, String> , invert , , grouping — Map .
Map :
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry EntryStream .
. , - . — GitHub , Maven Central . JavaDoc , . , , - . Entry<String, List> Entry<String, String> , invert , , grouping — Map .
Map :
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry EntryStream .
. , - . — GitHub , Maven Central . JavaDoc , . , , - . Entry<String, List> Entry<String, String> , invert , , grouping — Map .
Map :
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry EntryStream .
. , - . — GitHub , Maven Central . JavaDoc , . , , - . Entry<String, List> Entry<String, String> , invert , , grouping — Map .
Map :
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry EntryStream .
. , - . — GitHub , Maven Central . JavaDoc , . , , - . Entry<String, List> Entry<String, String> , invert , , grouping — Map .
Map :
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry EntryStream .
. , - . — GitHub , Maven Central . JavaDoc , . , , - . Entry<String, List> Entry<String, String> , invert , , grouping — Map .
Map :
public Map<String, String> stringMap(Map<Object, Object> map) { return EntryStream.of(map).mapKeys(String::valueOf).mapValues(String::valueOf).toMap(); }
, :
Map<String, Group> nameToGroup; public Map<String, List<User>> getGroupMembers(Collection<String> groupNames) { return StreamEx.of(groupNames).mapToEntry(nameToGroup::get).nonNullValues().mapValues(Group::getMembers).toMap(); }
mapToEntry EntryStream .
. , - . — GitHub , Maven Central . JavaDoc , . , , - .Source: https://habr.com/ru/post/255659/
All Articles