简体   繁体   English

如何迭代列表<? extends E>在 Java 中并使用实际对象?

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

So I know that to iterate I can use either for-each or Iterator.所以我知道要迭代我可以使用 for-each 或 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<? extends E> myList;
List<? extends E> newList = new ArrayList<>();
for(E element: myList) {
   if(element.getName().equals("abc")) {
      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?有什么不同的方法来解决这个问题吗?

You can try like that:你可以这样尝试:

List<? extends E> newList = myList.stream().filter(x -> x.getName().equals("abc")).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<?那么您将需要在循环内部检查元素是否是某个类的实例,但无法将您的元素添加到 List<? extends E>扩展 E>

So this will work:所以这将起作用:

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); // would throw an error because the list is of a different type.
                }

            }
        }

    }

This also will work这也将工作

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); // would throw an error because the list is of a different type.
                }

            }
        }

    }

But this won't work:但这行不通:

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); // would throw an error because the list is of a different type.
                }

            }
        }

    }

You can't add any non- null values to a List<? extends E>您不能将任何非null值添加到List<? extends E> List<? extends E> , because the compiler can't verify that the type matches the unknown type. List<? extends E> ,因为编译器无法验证该类型是否与未知类型匹配。

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<? extends E> myList;
List<? extends E> newList = filterList(myList);
...

private <T extends E> List<T> filterList(List<T> myList) {
  List<T> newList = new ArrayList<>();
  for(T element: myList) {
    if(element.getName().equals("abc")) {
        newList.add(element);
    }
  }
  return newList;
}

This way you basically "name" the anonymous type ? extend E这样你基本上“命名”匿名类型? extend E ? extend E and call it T for the duration of the method call. ? extend E并在方法调用期间将其称为T Now the compiler knows that what you're doing is legit.现在编译器知道你在做什么是合法的。

我做了类似的事情

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

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

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