【问题标题】:Foreach in a foreach removing items from listForeach 在 foreach 中从列表中删除项目
【发布时间】:2019-10-26 06:01:28
【问题描述】:

我正在根据它是谁创建一个 Java 应用程序?现在我正在制作一种方法,在回答问题时我想要其他卡片。

我有两个列表:

列表是一个 ImageView 列表,其中有 24 个卡片必须代表的图像视图。

另一个列表是 24 个地图对象的列表。

现在,如果图像视图的 ID 与 ImageView 中的卡片名称相同,我想从 ImageView 列表中删除 ImageViews。

我尝试在 foreach 中执行 foreach,然后从列表中删除一个项目,但我无法弄清楚。

我创建的方法:

public List<ImageView> getImageViews(List<Card> newCards){

    for (ImageView imageView: new ArrayList<>(allCards)) {
        String imageName = imageView.getId().toLowerCase();

        for (Card card: new ArrayList<>(newCards)){
            String cardName = card.getName().toLowerCase();

            if (!imageName.equals(cardName)){
                allCards.remove(imageView);
            }
        }
    }

    return allCards;
}

【问题讨论】:

    标签: java list loops foreach


    【解决方案1】:

    一些提示:

    1) allCards.remove(imageView); 仅当 equals() 在 ImageView 中被覆盖时才会起作用

    2) 这意味着如果连接元素不匹配,您要移除卡片:

    if (!imageName.equals(cardName)){
        allCards.remove(imageView);
    }
    

    只有当它匹配时你才会删除元素:

    现在我想从 ImageView 列表中删除 ImageViews 如果一个 ID 图像视图与 ImageView 中卡片的名称相同。

    这种方式会更好:

    if (imageName.equals(cardName)){
        allCards.remove(imageView);
        break; // to go back to the outer loop
    }
    

    使用 Iterator,您可以使事情变得更简单,而无需依赖 equals() 覆盖:

    public List<ImageView> getImageViews(List<Card> newCards){
        for (Iterator<ImageView> imageViewIt = allCards.iterator(); imageViewIt.hasNext();) {
            ImageView imageView = imageViewIt.next();
            String imageName = imageView.getId().toLowerCase();
            for (Card card: newCards){
                String cardName = card.getName().toLowerCase();
                if (imageName.equals(cardName)){
                    imageViewIt.remove();
                    break;
                }
            }
        }
        return allCards;
    }
    

    而使用 Java 8,您甚至可以做到这一点:

    public List<ImageView> getImageViews(List<Card> newCards){
        allCards.removeIf(view -> 
                           newCards.anyMatch(card -> 
                                    card.getName().equalsIgnoreCase(view.getId())
                         );
       return allCards;
    }
    

    此代码有效。

    【讨论】:

    • 回到这个问题,代码有效,只有当我第二次运行它时 allCards 保留旧值。例如,如果程序运行过一次,那么 allCards 的值为 8,这也是正确的,因为必须取出 8 张卡片。只有当我现在再次运行它时,值仍然是 8,而我必须拥有剩余的卡。希望你能帮我解决这个问题。
    【解决方案2】:

    我尝试在 foreach 中做一个 foreach,然后从 列表,但我想不通。

    只需使用普通的for 循环,然后根据索引使用allCards 中的项目删除。

    代码片段:

    public List<ImageView> getImageViews(List<Card> newCards){
        for (int i = 0; i < newCards.size(); i++) {
            String cardName = newCards.get(i).getName().toLowerCase();
            for (int j = 0; j < allCards.size(); j++){
                String imageName = allCards.get(j).getId().toLowerCase();
                if (imageName.equals(cardName)){
                    allCards.remove(j);
                    break;
                }
            }
        }
        return allCards;
    }
    

    【讨论】:

    • 感谢您的回复,仅...返回所有 24 张卡片。
    • @TomvandenBogaart 我的错,if 条件不应该有 !,因为您试图在名称匹配时删除该项目。尝试使用更新的代码。
    【解决方案3】:

    只需制作另一个数组。更简单,更少的代码。我的 Java 可能不完全正确,已经有一段时间了。但希望你能明白:

    public List<ImageView> getImageViews(List<Card> newCards){
     List<Card> returnObject = new List<Card>();
    for (ImageView imageView: new ArrayList<>(allCards)) {
        String imageName = imageView.getId().toLowerCase();
    
        for (Card card: new ArrayList<>(newCards)){
            String cardName = card.getName().toLowerCase();
    
              //Instead of a NOT, let's look for an IS
            if (imageName.equals(cardName)){
                returnObject.add(imageView)
            }
        }
    }
    
    return allCards;
    

    }

    【讨论】:

      猜你喜欢
      • 2010-11-02
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多