Let's say I have list of objects, each containing own array of Strings. I need to find objects that have most duplicates with given array. I can simply achive that by using some for loops, if and counters, but I want to do that using Java 8 streams. I really hope it is possible.
@Test
public void test() {
String mainArray[] = {"a", "b", "c"};
List<ElementsList> elems = new ArrayList<>();
ElementsList a = new ElementsList(new String[]{"d", "e", "a"});
ElementsList b = new ElementsList(new String[]{"b", "c", "d"});
elems.add(a);
elems.add(b);
List<ElementsList> result = elems.stream()...;
assertTrue(result.contains(b));
}
private class ElementsList {
private String elements[];
private ElementsList(String elements[]) {
this.elements = elements;
}
public String[] getElements() {
return elements;
}
}
stream() method only works for primitive arrays of int[], long[], and double[] type, and returns IntStream, LongStream and DoubleStream respectively. For other primitive types, Arrays. stream() won't work.
The stream(T[] array) method of Arrays class in Java, is used to get a Sequential Stream from the array passed as the parameter with its elements. It returns a sequential Stream with the elements of the array, passed as parameter, as its source.
Get the stream of elements in which the duplicates are to be found. For each element in the stream, count the frequency of each element, using Collections. frequency() method. Then for each element in the collection list, if the frequency of any element is more than one, then this element is a duplicate element.
I can think of this for example:
List<String> main = Arrays.asList(mainArray);
Stream.of(a, b)
.map(x -> new AbstractMap.SimpleEntry<>(x, new ArrayList<>(new ArrayList<>(Arrays.asList(x.elements)))))
.map(entry -> {
entry.getValue().removeAll(main);
entry.setValue(entry.getValue());
return entry;
})
.sorted(Comparator.comparing(e -> e.getValue().size()))
.map(Entry::getKey)
.forEach(el -> System.out.println(Arrays.toString(el.elements)));
Basically put all the elements into a mutable List
and do a removeAll
of the ones from mainArray
and sort the result based on the size of the remaining ones.
Here's a straightforward approach:
import static java.util.Comparator.comparingLong;
Set<String> mainSet = new HashSet<>(Arrays.asList(mainArray));
ToLongFunction<ElementsList> countMatches = el ->
Arrays.stream(el.getElements())
.filter(mainSet::contains)
.count();
ElementsList result = elems.stream()
.max(comparingLong(countMatches))
.get(); // or throw if elems is empty
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With