而不是交叉两个列表如何交叉两个以上?

时间:2017-07-15 18:13:53

标签: java arraylist

所以结构是{{Dog,Cat,Human},{Human,Dog,Whale,rabbit,Cow},{Monkey,Human,Dog}}

输出应为:Dog,Human

我必须在较大的List中找到List元素的交集。以前,我已经看到了找到单独ArrayLists的交集的代码,但不确定如何在同一ArrayList(两个以上)内完成。

对于单独的ArrayLists代码,如下所示。但是,如何让它在一个较大ArrayLists内的多个ArrayList中运行?我在接受采访时被问到这个问题。为单独的列表工作,但无法为同一个ArrayList粉笔。

面试官明确表示只能使用字符串,因此我在澄清后将{Geo> Generic类型令牌从{<T>}修改为{<String>}

public class Test {

    public <String> List<String> intersection(List<String> list1, List<String> list2) {
        List<String> list = new ArrayList<>();

        for (String t: list1) {
            if(list2.contains(t)) {
                list.add(t);
            }
        }

        return list;
    }
public static void main(String[] args) throws Exception {

        List<String> list1 = new ArrayList<String>(Arrays.asList("Dog", "Cat", "Human"));
        List<String> list2 = new ArrayList<String>(Arrays.asList("Human", "Dog", "Whale", "rabbit", "Cow"));

        System.out.println(new Test().intersection(list1, list2));

    }
}

这会为两个单独的ArrayLists生成正确的输出。但是,如果稍微修改了输入,例如,交集方法将为输入a,a,aa,a,a返回a,a,,但它将为输入a,a提供a,a {1}}和a,a,a。逻辑假设是,无论参数的顺序如何,它都应始终返回a,a

关于如何解决此问题的任何建议,无论输入顺序如何?我怎么能在一个更大的列表中找到几个列表(两个以上)的交集?

4 个答案:

答案 0 :(得分:6)

交点为associative,您可以实现两个列表的交集,然后将相同的算法重复应用于其余列表。

Java提供了一种通过retainAll操作进行交集的内置方法:

List<String> a = ...
List<String> b = ...
List<String> c = ...
List<String> intersection = new ArrayList<>(a);
intersection.retainAll(b);
intersection.retainAll(c);

答案 1 :(得分:2)

您可以使用Streamfilter

来交叉列表
List<String> list1 = new ArrayList<String>(Arrays.asList("Dog", "Cat", "Human"));
List<String> list2 = new ArrayList<String>(Arrays.asList("Human", "Dog", "Whale", "rabbit", "Cow"));
System.out.println(list1.stream()
            .filter(list2::contains)
            .collect(Collectors.toList()));

输出:

[Dog, Human]

答案 2 :(得分:2)

假设intersection有效,只需使用intersection折叠列表列表:

List<ArrayList<String>> lists = /* Lists of lists here */;

List<String> finalIntersection =
    lists.stream()
        .reduce(intersection)
        .collect(Collectors.toList())

未经测试,但提供的intersection类型匹配reduce期望的内容,reduce有一个重载,允许累加器作为第一个元素启动,它应该有效。

不幸的是,由于Java只有一个reduce方法用于流,因此这个解决方案很臃肿。在Clojure(另一种JVM语言)中,大致相当的代码片段就是:

(reduce intersection lists)

哪个很可爱。

答案 3 :(得分:1)

您需要做的就是以这种方式重复调用交集方法 -

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class HelloWorld{

 public static void main(String []args){
    List<String> list1 = new ArrayList<String>(Arrays.asList("Dog", "Cat", "Human"));
    List<String> list2 = new ArrayList<String>(Arrays.asList("Human", "Dog", "Whale", "rabbit", "Cow"));

    List<List<String>> lists=new ArrayList<List<String>>();

    lists.add(list1);
    lists.add(list2);
    Iterator<List<String>> iterator=lists.iterator();
    List<String>intersect=null;
    while(iterator.hasNext()){
        List<String> current=iterator.next();
            if(intersect==null){
              intersect=current;
            }
            else{
                intersect=intersection(intersect,current);
            }
    }
    System.out.println(intersect);
}

public static List<String> intersection(List<String> list1, List<String> list2) {
    List<String> list = new ArrayList<>();

    for (String t: list1) {
        if(list2.contains(t)) {
            list.add(t);
        }
    }

    return list;
}

}