繁体   English   中英

java中两个集合之间的公共元素

[英]common elements between two collections in java

  public class Task1 {

     public static void main(String[] args) {

        List<Task> mainList = new ArrayList<>();
        Task e = new Task();
        e.setId(1);
        e.setName("shiva");
        mainList.add(e);

        e.setId(2);
        e.setName("Jyothi");
        mainList.add(e);

        e.setId(3);
        e.setName("Dinnu");
        mainList.add(e);

        //System.out.println(mainList);

        List<Task> subList = new ArrayList<>();

        Task e1 = new Task();
        e1.setId(1);
        e1.setName("shiva");
        subList.add(e1);


        List<Task> finalList = getFinalList(mainList, subList);
    }

...

    private static List<Task> getFinalList(List<Task> mainList, List<Task> subList) {
        List<Task> finalList = new ArrayList<>();

        System.out.println("final List: "+mainList.retainAll(subList));

        for(Task o : mainList){

            for(Task o1 : subList){

                if (o.equals(o1)){

                                  finalList.add(o);
                }
            }
        }

        System.out.println(finalList);
        return finalList;

但是我仍然无法得到共同的元素。我可以告诉你我犯错了。

这是一个相当简单的解决方案:

public static void main(String[] args) {
    List<String> list1 = new ArrayList<String>() {
        {
            add("string 1");
            add("string 2");
            add("string 3");
            add("string 4");
        }
    };
    List<String> list2 = new ArrayList<String>() {
        {
            add("string 4");
            add("string 5");
            add("string 3");
            add("string 6");
            add("string 3");
        }
    };

    Set<String> hash1 = new HashSet<>(list1);
    Set<String> hash2 = new HashSet<>(list2);

    hash1.retainAll(hash2);

    System.out.println(hash1);
}

这打印

[string 4,string 3]

大多数代码都是设置值。 不要忘记在自定义类中实现.equals(Object o).hashCode()

您需要为Task类编写适当的equals()方法。 您创建了两个不同的Task对象,默认的equals()实现在这种情况下不起作用。 编写一个自定义的equals(),适当地比较id和名称!

编辑:此外,看起来您实际上并没有为第一个列表创建三个任务。 您创建一个新任务,然后更改其值。 如果在完成设置后打印出mainList的大小,它可能在三次内部具有相同的Task对象。

一种可能性是使用Set数据结构(不允许重复),你可以很容易地找到两组之间的联合。 例如Google Guava提供了这一点。

每次mainList只有一个对象时,您修改了相同的实例

像这样重新创建它

    List<Task> mainList = new ArrayList<Task>();
    Task e = new Task();
    e.setId(1);
    e.setName("shiva");
    mainList.add(e);

    Task e1 = new Task();
    e1.setId(2);
    e1.setName("Jyothi");
    mainList.add(e1);

    Task e12 = new Task();
    e12.setId(3);
    e12.setName("Dinnu");
    mainList.add(e12);

    //System.out.println(mainList);

    List<Task> subList = new ArrayList<Task>();

    Task e13 = new Task();
    e13.setId(1);
    e13.setName("shiva");
    subList.add(e13);

并删除此行...

      System.out.println("final List: "+mainList.retainAll(subList));

采用

      for(Task o : mainList){

        for(Task o1 : subList){

            if( ( o.getId() == o1.getId() ) && o.getName().equals(o1.getName()) ){
                                finalList.add(o);
      }     
        }
    }

    System.out.println(finalList);
    return finalList;

在Task中实现hasCode()方法(如果你使用eclipse IDE意味着按下alt + shift + s - >生成哈希码和equals()它会自动生成)

我看到一件事肯定是错的,这里有一件事可能是错的。

首先,当您完成添加到第一个列表后,该列表包含对同一个Task实例的三个引用。 基本上,列表中有三个任务引用,它们都具有id = 3和name =“dinnu”。 我猜你可能打算这样做:

List<Task> mainList = new ArrayList<>();
Task e = new Task();
e.setId(1);
e.setName("shiva");
mainList.add(e);

e = new Task(); //Make a new instance
e.setId(2);
e.setName("Jyothi");
mainList.add(e);

e = new Task(); //Make a new instance
e.setId(3);
e.setName("Dinnu");
mainList.add(e);

基本上,由于您忘记创建新实例,因此您只需更改同一对象上的值而不是创建新对象。

第二个潜在的问题是Java Collections将在Task Object上使用“equals()”方法来确定对象相等性。 如果你没有,它只会检查对象是否引用相同的对象实例,而不是比较对象的属性。 因此,您可能需要在Task对象上实现equals()方法,如果您还没有。

如果修复了这些内容,那么调用mainList.retainAll(subList)将删除mainList中subList中不存在的所有元素。 (finalList不是必需的 - 该调用只会编辑mainList)

如果您想保留mainList而不是编辑它,那么请执行以下操作:

List<Task> finalList = new ArrayList<>(mainList); //Copy main into finalList
finalList.retainAll(subList); //remove elements that are not present in subList

一种方法是使用哈希表而不是列表。 因为你有String和整数hasgtable将是你的场景的理想解决方案,然后你可以使用这样的东西来找到两个哈希表中的交叉值。

Hashtable<String, Integer> inersect = new Hashtable<String, Integer>(hashtable1);
inersect.keySet().retainAll(hashtable2.keySet());
System.out.println(inersect);

equals自定义对象的方法任务需要通过使Task类实现Comparable Class来实现。

class Task implements Comparable<Task>{

@Override
public int compareTo(Task o) {
    return (o.getId()==this.getId() && o.getName().equals(this.getName());
}
//other class functions
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM