java 将 Collection<SomeClass> 转换为 Collection<SomeSuperClass>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2460951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
casting Collection<SomeClass> to Collection<SomeSuperClass>
提问by skrebbel
I'm sure this has been answered before, but I really cannot find it.
我确定之前已经回答过这个问题,但我真的找不到。
I have a java class SomeClassand an abstract class SomeSuperClass. SomeClassextends SomeSuperClass.
我有一个 java 类SomeClass和一个抽象类SomeSuperClass。SomeClass延伸SomeSuperClass。
Another abstract method has a method that returns a Collection<SomeSuperClass>. In an implementation class, I have a Collection<SomeClass> myCollection
另一个抽象方法有一个返回 a 的方法Collection<SomeSuperClass>。在一个实现类中,我有一个Collection<SomeClass> myCollection
I understand that I cannot just return myCollection, because Collection<SomeClass>does not inherit from Collection<SomeSuperClass>. Nevertheless, I know that everything in myCollectionis a SomeSuperClassbecause after all, they're SomeClassobjects which extend SomeSuperClass.
我明白我不能只是返回myCollection,因为Collection<SomeClass>不继承自Collection<SomeSuperClass>. 尽管如此,我知道里面的一切myCollection都是 aSomeSuperClass因为毕竟它们是SomeClass扩展SomeSuperClass.
How can I make this work?
我怎样才能使这项工作?
I.e. I want
即我想要
public class A
{
private Collection<SomeClass> myCollection;
public Collection<SomeSuperClass> getCollection()
{
return myCollection; //compile error!
}
}
The only way I've found is casting via a non-generic type and getting unchecked warnings and whatnot. There must be a more elegant way, though? I feel that also using Collections.checkedSet()and friends are not needed, since it is statically certain that the returned collection only contains SomeClassobjects (this would not be the case when downcasting instead of upcasting, but that's not what I'm doing). What am I missing?
我发现的唯一方法是通过非通用类型进行转换并获得未经检查的警告等等。不过,一定有更优雅的方式吗?我觉得Collections.checkedSet()也不需要使用和朋友,因为静态地确定返回的集合只包含SomeClass对象(向下转换而不是向上转换时情况并非如此,但这不是我正在做的)。我错过了什么?
Thanks!
谢谢!
采纳答案by Steven Schlansker
You can't do this. You have a Collection<SomeClass> and wish to return a Collection<SuperClass>
你不能这样做。你有一个 Collection<SomeClass> 并希望返回一个 Collection<SuperClass>
Now imagine that someone has your returned Collection - and they try to insert a differentsubclass of SuperClass, SomeOtherClass. This should be allowed on your SuperClass collection - but it can't because it's actually a Collection<SomeClass>, unbeknownst to anyone but the private member of A.
现在假设有人拥有您返回的集合 - 他们尝试插入SuperClass的不同子类 SomeOtherClass。这应该在您的 SuperClass 集合中被允许 - 但它不能,因为它实际上是一个 Collection<SomeClass>,除了 A 的私有成员之外,任何人都不知道。
回答by ishmeister
Will Collection<? extends SomeSuperClass>not do what you want?
不会Collection<? extends SomeSuperClass>为所欲为?
回答by Vlad Schnakovszki
Java 8now offers a neater way of doing it using lambdas: you can use the map() and collect()functions to cast the objects to your super class. A solution for your example would look like this:
Java 8现在提供了一种使用lambdas的更简洁的方法:您可以使用map() 和 collect()函数将对象转换为您的超类。您的示例的解决方案如下所示:
public class A
{
private Collection<SomeClass> myCollection;
public Collection<SomeSuperClass> getCollection()
{
return myCollection.stream().map(x -> (SomeSuperClass) x).collect(Collectors.toList());
}
}
You can also use other Collectorsif needed.
如果需要,您还可以使用其他收集器。
回答by Konstantin
If you create a new collection of the correct type you can populate it using the old collection
如果您创建了正确类型的新集合,则可以使用旧集合填充它
public Collection<SomeSuperClass> getCollection()
{
return new ArrayList<SomeSuperClass>(myCollection);
}
回答by Davi
Based on the top answer given to this question: How do you cast a List of supertypes to a List of subtypes?
基于对这个问题给出的最佳答案: 如何将超类型列表转换为子类型列表?
I do believe it is possible to do
我相信有可能做到
Collection<SomeSuperType> variable =
(Collection<SomeSuperType>)(Collection<?>) collectionOfSomeType;
At the expense of an "unchecked" warning. At the linked question, concern has been expressed about the "hackiness" of this answer due to the lack of type safety. However, in this question's context (namely casting a collection of subtypes to a collection of their supertypes) I see no problems or possible ClassCastExceptions. And in any case, it works quite well.
以“未经检查”的警告为代价。在链接的问题上,由于缺乏类型安全性,有人对此答案的“hackiness”表示担忧。但是,在这个问题的上下文中(即将子类型的集合转换为它们的超类型的集合),我看不到任何问题或可能的 ClassCastExceptions。无论如何,它运作良好。
回答by Adam111p
Yes we can!
我们可以!
class A {@Override
public String toString()
{
return "A";
} };
class B extends A {
@Override
public String toString()
{
return "B";
}
};
List<A> l1 = new ArrayList<A>();
l1.add(new A());
List<B> l2 = null;
l2 = (List<B>)(List<? extends A>)l1;
l2.add(new B());
System.out.println( Arrays.toString( l2.toArray() ) );
please test it
请测试一下
回答by Stefan Hendriks
I am not sure why; perhaps someone else can explain this; but it works if you do:
我不知道为什么;也许其他人可以解释这一点;但如果你这样做,它会起作用:
public abstract class SomeSuperClass<E> {
abstract public Collection<SomeSuperClass<E>> getCollection();
}
and:
和:
public class Someclass extends SomeSuperClass {
@Override
public Collection<Someclass> getCollection() {
// TODO Auto-generated method stub
return null;
}
}
回答by Stefan Hendriks
perhaps, you should do some workaround.
也许,您应该做一些解决方法。
for example, you should make some "HolderClass" with generic extension, and then you'll be able to put weather your SomeClass, weather your SomeSuperClass.
例如,您应该制作一些具有通用扩展名的“HolderClass”,然后您就可以将 Weather 您的 SomeClass 放在 Weather 您的 SomeSuperClass 中。
take a look:
看一看:
public class HolderClass<E extends SomeSuperClass> {
private final Collection<E> myClass;
public HolderClass() {
myClass = new ArrayList<E>();
}
public void putSomeClass(final E clazz) {
myClass.add(clazz);
}
public Collection<E> getMyClasses() {
return myClass;
}
}
and you can make collection this way:
你可以这样收集:
HolderClass<SomeSuperClass> holderClass = new HolderClass<SomeSuperClass>();
holderClass.putSomeClass(new SomeClass());
holderClass.putSomeClass(new SomeSuperClass());
and now, when you make call to getMyClasses(), you'll get collection of SomeSuperClasses
现在,当您调用 getMyClasses() 时,您将获得 SomeSuperClasses 的集合
回答by Kip
.NET 4.0 introduces covariance and contravariance to generics:
.NET 4.0 为泛型引入了协变和逆变:
http://msdn.microsoft.com/en-us/library/dd799517(VS.100).aspx
http://msdn.microsoft.com/en-us/library/dd799517(VS.100).aspx
回答by Everyone
A collection of SubType is not substitutablefor SuperType.
SubType 的集合不能替代SuperType。

