【问题标题】:find common and different elements between two List in java在java中的两个List之间找到共同和不同的元素
【发布时间】:2017-04-03 09:34:50
【问题描述】:

我想得到以下
1. 两个列表之间的共同元素。
2. ListB 中没有 ListA 的元素
3. ListA中ListB中没有的元素

List<String> fruitsListA = new ArrayList<String>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grapes");
List<String> fruitsListACopy = fruitsListA;

List<String> fruitsListB = new ArrayList<String>();
fruits.add("Strawberry");
fruits.add("Cranberry");
fruits.add("Orange");
fruits.add("Apple");
List<String> fruitsListBCopy = fruitsListB;

1. common elements between two list

    fruitsListACopy.retainAll(fruitsListB);

2. Elements in ListB which is not available in ListA

    fruitsListB.removeAll(fruitsListA);

3. Elements in ListA which is not available in ListB

    fruitsListA.removeAll(fruitsListBCopy);

案例 1:我能够获得两个列表中的共同项目。所以如果我打印 fruitsListACopy 它会给出 ['Apple']

案例 2:我可以看到 fruitsListA 被自动修改了我的意思是它没有所有的项目 ['Apple','Banana','Grapes'] 它只有共同的项目 ['苹果'] 。

案例 3:我可以看到 fruitsListB 被自动修改了我的意思是它没有所有项目 ['Strawberry','Cranberry','Orange','Apple'] ['Strawberry','Cranberry','Orange'] 移除了苹果的 coomon 项目。
我什至可以看到 fruitsListA 被自动修改了我的意思是它没有所有项目 ['Apple','Banana','Grapes'] 它只有共同的项目 ['苹果'] 。

当我使用 removeAll 和 retainAll 方法时,复制列表中所做的更改会反映在原始列表中。

还有其他最好的方法来满足这个需求吗?

【问题讨论】:

  • 复制的变量是引用。他们指向原始列表。因此,如果您对复制的变量进行更改,它们也会更新原始列表。
  • 您需要对您的列表执行所谓的deep copy,而不是您现在正在执行的shallow copy,因为您的列表中只包含引用。

标签: java


【解决方案1】:

创建一个新实例,而不是将同一个对象分配给另一个引用。

例如,您可以替换:

    List<String> fruitsListACopy = fruitsListA;

通过

    List<String> fruitsListACopy = new ArrayList<>(fruitsListA);

如果您不希望对复制列表的操作之间产生副作用,则必须在对其进行每次操作之前创建原始列表的新副本。

然后您必须在复制的列表上调用retainAll()removeAll(),并将原始列表作为方法的参数提供。

这里有一个示例代码来说明:

public static void main(String[] args) {
    List<String> fruitsListA = new ArrayList<String>();
    fruitsListA.add("Apple");
    fruitsListA.add("Banana");
    fruitsListA.add("Grapes");

    List<String> fruitsListB = new ArrayList<String>();
    fruitsListB.add("Strawberry");
    fruitsListB.add("Cranberry");
    fruitsListB.add("Orange");
    fruitsListB.add("Apple");

    // copy for A
    List<String> fruitsListACopy = new ArrayList<>(fruitsListA);
    fruitsListACopy.retainAll(fruitsListB);
    // handle the result of fruitsListACopy
    System.out.println("fruitsListACopy="+fruitsListACopy);

    // copy for B
    List<String> fruitsListBCopy = new ArrayList<>(fruitsListB);
    fruitsListBCopy.removeAll(fruitsListA);
    // handle the result of fruitsListBCopy
    System.out.println("fruitsListBCopy="+fruitsListBCopy);

    // copy for A
    fruitsListACopy = new ArrayList<>(fruitsListA);
    fruitsListACopy.removeAll(fruitsListB);
    // handle the result of fruitsListACopy
    System.out.println("fruitsListACopy="+fruitsListACopy);
}

输出:

fruitsListACopy=[苹果]

fruitsListBCopy=[草莓、蔓越莓、橙子]

fruitsListACopy=[香蕉、葡萄]

【讨论】:

    【解决方案2】:

    我什至可以看到 fruitsListA 被自动修改了

    当你制作像 yhis 这样的副本时

    List<String> fruitsListACopy = fruitsListA;
    

    您不复制列表。相反,您引用现有列表。因此,对“副本”的所有修改都反映在原件上。

    要复制,再次调用构造函数:

    List<String> fruitsListACopy = new ArrayList<String>(fruitsListA);
    

    【讨论】:

    • 如何使列表保持不变。正如我的问题所问的,我需要在所有 3 种不同情况下获取元素?
    • @AlagammalP 制作副本可保护原始列表。确保不要在原始列表上调用修改方法,只在副本上调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2021-01-01
    • 2015-07-14
    相关资源
    最近更新 更多