如何在Java中迭代List并使用实际对象?

huangapple go评论67阅读模式
英文:

How to iterate over List<? extends E> in Java and use the actual object?

问题

我知道可以使用for-each或Iterator进行迭代。但我的问题是,我想通过根据条件删除一些元素来创建一个相同类型的新列表
例如-

List<? extends E> myList;
List<? extends E> newList = new ArrayList<>();
for (E element : myList) {
    if (element.getName().equals("abc")) {
        newList.add(element); // 会引发错误,因为列表是不同类型的。
    }
}

我该怎么做?有没有其他不同的方法来解决这个问题?

英文:

So I know that to iterate I can use either for-each or Iterator. But my problem is that I want to create a new list of the same type by removing some of the elements by a condition.
For ex-

List&lt;? extends E&gt; myList;
List&lt;? extends E&gt; newList = new ArrayList&lt;&gt;();
for(E element: myList) {
   if(element.getName().equals(&quot;abc&quot;)) {
      newList.add(element); // would throw an error because the list is of a different type. 
   }
}

How do I go about it? Is there any different way to tackle this?

答案1

得分: 2

你可以尝试这样做:

List<? extends E> newList = myList.stream().filter(x -> x.getName().equals("abc")).collect(Collectors.toList());

但是,如果你需要访问在"?"后面隐藏的类型,那么你需要在循环内部检查元素是否是某个特定类的实例,但是不可能将你的元素添加到 List<? extends E> 中。

因此,下面这个示例会起作用:

public static void main(String[] args) {
    List<? extends E> myList = new ArrayList<>();
    
    List<E> newList = new ArrayList<>();
    
    for (E element : myList) {
        if (element instanceof D) {
            D elementD = (D) element;
            if (elementD.getName().equals("abc")) {
                newList.add(elementD); // 会抛出错误,因为列表的类型不同。
            }
        }
    }
}

这个也会起作用:

public static void main(String[] args) {
    List<? extends E> myList = new ArrayList<>();
    
    List<D> newList = new ArrayList<>();
    
    for (E element : myList) {
        if (element instanceof D) {
            D elementD = (D) element;
            if (elementD.getName().equals("abc")) {
                newList.add(elementD); // 会抛出错误,因为列表的类型不同。
            }
        }
    }
}

但是这个不会起作用:

public static void main(String[] args) {
    List<? extends E> myList = new ArrayList<>();
    
    List<? extends E> newList = new ArrayList<>();
    
    for (E element : myList) {
        if (element instanceof D) {
            D elementD = (D) element;
            if (elementD.getName().equals("abc")) {
                newList.add(elementD); // 会抛出错误,因为列表的类型不同。
            }
        }
    }
}
英文:

You can try like that:

List&lt;? extends E&gt; newList = myList.stream().filter(x -&gt; x.getName().equals(&quot;abc&quot;)).collect(Collectors.toList());

But if you need type that is hidden behind "?" then you will need to check inside your loop if element is an instance of certain class but it is not possible to add your element into List<? extends E>

So this will work:

public static void main(String[] args) {
        List&lt;? extends E&gt; myList  = new ArrayList&lt;&gt;();;

        List&lt;E&gt; newList = new ArrayList&lt;&gt;();

        for(E element: myList) {
            if (element instanceof D) {
                D elementD = (D)element;
                if(elementD.getName().equals(&quot;abc&quot;)) {
                    newList.add(elementD); // would throw an error because the list is of a different type.
                }

            }
        }

    }

This also will work

public static void main(String[] args) {
        List&lt;? extends E&gt; myList  = new ArrayList&lt;&gt;();;

        List&lt;D&gt; newList = new ArrayList&lt;&gt;();

        for(E element: myList) {
            if (element instanceof D) {
                D elementD = (D)element;
                if(elementD.getName().equals(&quot;abc&quot;)) {
                    newList.add(elementD); // would throw an error because the list is of a different type.
                }

            }
        }

    }

But this won't work:

public static void main(String[] args) {
        List&lt;? extends E&gt; myList  = new ArrayList&lt;&gt;();;

        List&lt;? extends E&gt; newList = new ArrayList&lt;&gt;();

        for(E element: myList) {
            if (element instanceof D) {
                D elementD = (D)element;
                if(elementD.getName().equals(&quot;abc&quot;)) {
                    newList.add(elementD); // would throw an error because the list is of a different type.
                }

            }
        }

    }

答案2

得分: 0

你不能向List&lt;? extends E&gt;中添加任何非null值,因为编译器无法验证类型是否与未知类型匹配。

要允许这样做,你需要告诉编译器这两个列表实际上是相同类型的。你可以通过将代码提取到一个单独的方法中来实现:

List&lt;? extends E&gt; myList;
List&lt;? extends E&gt; newList = filterList(myList);
...

private &lt;T extends E&gt; List&lt;T&gt; filterList(List&lt;T&gt; myList) {
  List&lt;T&gt; newList = new ArrayList&lt;&gt;();
  for(T element: myList) {
    if(element.getName().equals(&quot;abc&quot;)) {
        newList.add(element);
    }
  }
  return newList;
}

这样,你基本上为匿名类型? extend E“命名”,并在方法调用期间将其称为T。现在编译器知道你所做的是合法的。

英文:

You can't add any non-null values to a List&lt;? extends E&gt;, because the compiler can't verify that the type matches the unknown type.

You'd need to tell the compiler that the two lists are actually of the same type to allow that. You can do that by extracting the code to a separate method:

List&lt;? extends E&gt; myList;
List&lt;? extends E&gt; newList = filterList(myList);
...

private &lt;T extends E&gt; List&lt;T&gt; filterList(List&lt;T&gt; myList) {
  List&lt;T&gt; newList = new ArrayList&lt;&gt;();
  for(T element: myList) {
    if(element.getName().equals(&quot;abc&quot;)) {
        newList.add(element);
    }
  }
  return newList;
}

This way you basically "name" the anonymous type ? extend E and call it T for the duration of the method call. Now the compiler knows that what you're doing is legit.

答案3

得分: 0

我做了类似这样的事情:

mylist.removeIf(element -> element.getName().equals("abc"));
英文:

I did something like

mylist.removeIf(element -&gt; element.getName().equals(&quot;abc&quot;));

huangapple
  • 本文由 发表于 2020年9月15日 17:06:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63898589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定