【问题标题】:How to remove specific element from a list of list in java?如何从java列表中删除特定元素?
【发布时间】:2020-07-23 07:33:27
【问题描述】:

我使用 for 循环并制作 deepCopy 从列表列表中删除了特定元素。有没有其他方法可以从列表列表中删除特定元素?

import java.util.ArrayList;
import java.util.List;

public class HelloWorld{

     public static void main(String []args){
         List<ArrayList<String>> listA = new ArrayList<ArrayList<String>>();
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("cucumber");
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("carrot");
        ArrayList<String> list3 = new ArrayList<String>();
        list3.add("spinach");
        ArrayList<String> list4 = new ArrayList<String>();
        list4.add("kale");
        listA.add(list1);
        listA.add(list2);
        listA.add(list3);
        listA.add(list4);
        System.out.println("Original-->"+listA);

        List<List<String>> deepCopyOfListA = new ArrayList<List<String>>(listA);
        System.out.println("Deepcopy -->"+deepCopyOfListA);

        for (List<String> item : deepCopyOfListA) {
            if (item.contains("kale") || item.contains("cucumber")){
            listA.remove(item);
            }
        }
        System.out.println("Final-->"+listA);
    }
}

从下面的答案来看,这似乎是最方便的。 使用 Iterator 删除带有 if 条件的所需元素。经过测试,效果很好。谢谢各位的意见。

Iterator<ArrayList<String>> itr = listA.iterator();
    while(itr.hasNext()) {
        List<String> item = itr.next();
        if ((item.contains("cucumber") || item.contains("kale"))) {
            itr.remove();
        }

【问题讨论】:

  • 您正在删除整个列表,而不仅仅是元素
  • 您不是在制作浅拷贝,而不是深拷贝 - 这是您的实际代码吗?这里有什么问题?
  • 您的变量DeepCopyOfListA 不存在,也许您的意思是deepCopyOfListA? ost 你使用的实际代码
  • 按照你做的方式,从外部列表中,如果它有字符串cucumber,一个完整的内部列表将被删除。这是您想要做的,还是只想从内部列表中删除字符串 cucumber
  • 我已经编辑了代码以使其与我的工作相匹配。似乎我以前的代码没有让我的问题足够清楚。希望这次编辑能让问题更清楚。

标签: java list loops arraylist


【解决方案1】:

截至,如果你想从内部列表中删除某个元素,你必须先迭代外部的,然后使用List::removeIf到内部的:

// Mutates the original list
List<List<String>> outerList = ...            
for (List<String> innerList : outerList) {
    innerList.removeIf(item -> "cucumber".equals(item));
}

// Creates a new one while keeping the original untouched
List<List<String>> newList = outerList.stream()
    .map(innerList -> innerList.stream()
        .filter(item -> !"cucumber".equals(item))
        .collect(Collectors.toList()))
    .collect(Collectors.toList());

对于低于8的版本,您应该使用Iterator的正确删除方式:

for (final List<String> innerList: outerList) {
    Iterator<String> iterator = innerList.iterator();
    while (iterator.hasNext()) {
        if ("cucumber".equals(item)) {
            iterator .remove();
        }
    }
}

无论如何,请使用"cucumber".equals(item) 而不是item.equals("cucumber"),因为前者对空值友好。

【讨论】:

    【解决方案2】:

    您可以通过迭代列表来从列表列表中删除“黄瓜”。无需创建显式迭代器对象,无需使用怪异的“流”语法。无需创建副本 - 深或浅。当然,您可能仍想创建一个副本,以便您仍然拥有原始值 - 但这取决于您。

    List<List<String>> ListA=response.path("response.A");
    for (List<String> item : ListA) {
        item.remove("cucumber");
    }
    

    请注意,如果任何列表碰巧包含多个黄瓜,这将只删除第一个。

    【讨论】:

    • 我无法在迭代时从同一个列表中删除该元素。我收到错误“java.util.ConcurrentModificationException”。这就是为什么我必须创建原始列表的深层副本。
    • 在答案中使用代码 sn-p 时,您不会在迭代列表时从列表 ListA 中删除元素。您正在对该列表中的单个元素调用方法。
    【解决方案3】:
    DeepCopyOfListA.removeAll(
            ListA.stream()
            .filter(innerList -> innerList.stream()
               .anyMatch(str -> str.contains("cucumber")))
            .collect(Collectors.toList())
    );
    

    还想引起您的注意,根据 Java 代码约定,您应该使用小写(实际上是驼峰式)命名变量。所以,listA 和 deepCopyofListA。

    【讨论】:

    • 这是错误的。如果存在“黄瓜”,它会删除整个列表,而不仅仅是那个项目。
    • 是的。我之前有错字。否则我的变量是驼峰式的。
    【解决方案4】:

    不清楚是否要删除完整的内部列表(即item),如果它有字符串cucumber -或者-您只想从内部列表中删除字符串cucumber(即items)。下面给出了每种情况的解决方案。

    删除完整的内部列表(即item)如果它有字符串cucumber

    public void removeSpecificElement(Response response) {
        List<List<String>> listA = response.path("response.A");
        Iterator<List<String>> itr = listA.iterator();
        while(itr.hasNext()) {
            List<String> item = itr.next();
            if (item.contains("cucumber")) {
                itr.remove();
            }
        }
    }
    

    从内部列表中仅删除字符串cucumber(即item):

    public void RremoveSpecificElement(Response response) {
        List<List<String>> listA = response.path("response.A");
        for (List<String> item : listA) {
            item.removeAll(Collections.singleton("cucumber"));
        }
    }
    

    【讨论】:

    • 我想删除有字符串黄瓜的内部列表。使用迭代器是个好主意。谢谢!
    猜你喜欢
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多