'Java 8 Stream filtering value of list in a list
I have a an object which looks like the following
class MyObject {
String type;
List<String> subTypes;
}
Is it possible, given a list of MyObject's to use Java 8 streams to filter on both the type and then the subtype?
So far I have
myObjects.stream()
.filter(t -> t.getType().equals(someotherType)
.collect(Collections.toList());
but within this I also want another filter on each of the subTypes filtering those on a particular subtype too. I can't figure out how to do this.
An example would be
myObject { type: A, subTypes [ { X, Y, Z } ] }
myObject { type: B, subTypes [ { W, X, Y } ] }
myObject { type: B, subTypes [ { W, X, Z } ] }
myObject { type: C, subTypes [ { W, X, Z } ] }
I would pass in matchType B and subType Z, so I would expect one result -> myObject type B, subtypes: W, X, Z
the following currently returns 2 items in a list.
myObjects.stream()
.filter(t -> t.getType().equals("B")
.collect(Collectors.toList());
but I would like to add an additional filter over the each of the subtypes and only matching where 'Z' is present.
Solution 1:[1]
I saw the accepted answer from @kocko which is both a good answer and totally correct. However there is a slightly alternative approach where you simply chain the filters.
final List<MyObject> withBZ = myObjects.stream()
.filter(myObj -> myObj.getType().equals("B"))
.filter(myObj -> myObj.getSubTypes().stream().anyMatch("Z"::equals))
.collect(Collectors.toList());
This is basically doing the same thing but the && operand is removed in favour of another filter. Chaining works really well for the Java 8 Stream API:s and IMO it is easier to read and follow the code.
Solution 2:[2]
I found a bunch of examples at this site: https://zetcode.com/java/streamfilter/
Quoting the example for Java Stream multiple filter operations
It is possible to apply multiple filter operations on a stream.
package com.zetcode;
import java.util.Arrays;
import java.util.function.IntConsumer;
public class JavaStreamMultipleFilters {
public static void main(String[] args) {
int[] inums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
IntConsumer icons = i -> System.out.print(i + " ");
Arrays.stream(inums).filter(e -> e < 6 || e > 10)
.filter(e -> e % 2 == 0).forEach(icons);
}
}
In the example, we apply multiple filter operations on a stream of integers.
int[] inums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
We have an array of integer values.
IntConsumer icons = i -> System.out.print(i + " ");
IntConsumer is an operation that accepts a single integer value argument and returns no result.
Arrays.stream(inums).filter(e -> e < 6 || e > 10)
.filter(e -> e % 2 == 0).forEach(icons);
A stream is created from the array with the Arrays.stream method. Multiple filtering operations are performed.
2 4 12 14
These integers fulfill all the filtering conditions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | wassgren |
| Solution 2 | rjose |
