假设我有对象列表,每个对象都包含自己的字符串数组。我需要找到与给定数组具有最多重复的对象。 我可以简单地通过使用一些for循环,if和counter来实现,但我想使用Java 8流来实现。我真的希望有可能。
@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;
}
}
答案 0 :(得分:4)
我可以这样想:
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)));
基本上将所有元素放入可变List
并从removeAll
中执行mainArray
个元素,并根据剩余元素的大小对结果进行排序。
答案 1 :(得分:1)
这是一个直截了当的方法:
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
答案 2 :(得分:0)
当列表具有不同的大小时,此解决方案更好。
List<String> main = Arrays.asList(mainArray);
Stream.of(a, c, b)
.map(x -> new AbstractMap.SimpleEntry<>(x, new ArrayList<>(main)))
.peek(entry -> {
entry.getValue().removeAll(Arrays.asList(entry.getKey().elements));
entry.setValue(entry.getValue());
})
.sorted(Comparator.comparing(e -> e.getValue().size()))
.map(Map.Entry::getKey)
.forEach(el -> System.out.println(Arrays.toString(el.elements)));