【问题标题】:Finding two similar arrays using streams使用流查找两个相似的数组
【发布时间】:2017-09-05 10:43:55
【问题描述】:

假设我有一个对象列表,每个对象都包含自己的字符串数组。我需要找到与给定数组重复最多的对象。 我可以通过使用一些 for 循环、if 和计数器来简单地实现这一点,但我想使用 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;
    }
}

【问题讨论】:

  • 在 ElementList 中或列表之间重复?
  • 给定数组(此处为 mainArray)和 ElementList 中的数组之间

标签: arrays java-8 java-stream


【解决方案1】:

我可以这样想:

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,并对来自mainArray 的元素进行removeAll,并根据剩余元素的大小对结果进行排序。

【讨论】:

    【解决方案2】:

    这是一个简单的方法:

    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
    

    【讨论】:

      【解决方案3】:

      当列表大小不同时,此解决方案更好。

      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)));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-01
        • 2012-08-12
        • 1970-01-01
        • 2022-10-16
        • 2018-07-13
        • 1970-01-01
        • 2017-07-19
        相关资源
        最近更新 更多