代码之家  ›  专栏  ›  技术社区  ›  skrebbel

将集合<SomeClass>转换为集合<SomeSuperClass>

  •  22
  • skrebbel  · 技术社区  · 16 年前

    我有一个java类 SomeClass 和一个抽象类 SomeSuperClass . 某类 某个超类 .

    另一个抽象方法有一个返回 Collection<SomeSuperClass> Collection<SomeClass> myCollection

    我明白我不能就这样回来 myCollection ,因为 Collection<SomeClass> 不继承自 . 不过,我知道 是一个 某个超类 某类 某个超类 .

    我怎样才能做到这一点?

    也就是说,我想要

    public class A
    {
      private Collection<SomeClass> myCollection;
    
      public Collection<SomeSuperClass> getCollection()
      {
        return myCollection; //compile error!
      }
    }
    

    Collections.checkedSet() 并且不需要朋友,因为静态地确定返回的集合只包含 某类 对象(向下投射而不是向上投射时不会出现这种情况,但我不是这样做的)。我错过了什么?

    10 回复  |  直到 16 年前
        1
  •  11
  •   Steven Schlansker    16 年前

    你不能这么做。您有一个收藏<SomeClass>并希望归还一份收藏品<超类>

    不同的

        2
  •  22
  •   ishmeister    16 年前

    威尔 Collection<? extends SomeSuperClass> 不做你想做的?

        3
  •  6
  •   Vlad Schnakovszki Rohit kumar    10 年前

    Java 8 现在提供了一种使用 lambdas :您可以使用 map() and collect()

    public class A
    {
        private Collection<SomeClass> myCollection;
    
        public Collection<SomeSuperClass> getCollection()
        {
            return myCollection.stream().map(x -> (SomeSuperClass) x).collect(Collectors.toList());
        }
    }
    

    您也可以使用其他 Collectors

        4
  •  1
  •   Konstantin    11 年前

    如果创建正确类型的新集合,则可以使用旧集合填充它

    public Collection<SomeSuperClass> getCollection()
    {
        return new ArrayList<SomeSuperClass>(myCollection); 
    }
    
        5
  •  1
  •   Community Mohan Dere    9 年前

    How do you cast a List of supertypes to a List of subtypes?

    Collection<SomeSuperType> variable =
                        (Collection<SomeSuperType>)(Collection<?>) collectionOfSomeType;
    

    以“未经检查”的警告为代价。在相关问题上,由于缺乏类型安全性,有人对这个答案的“黑客性”表示担忧。然而,在这个问题的上下文中(即将子类型的集合转换为它们的父类型的集合),我看不到任何问题或可能的ClassCastExceptions。不管怎么说,效果都很好。

        6
  •  0
  •   Stefan Hendriks    16 年前

    我不知道为什么;也许其他人可以解释这一点;但如果你这么做了:

    public abstract class SomeSuperClass<E> {
        abstract public Collection<SomeSuperClass<E>> getCollection();
    }
    

    public class Someclass extends SomeSuperClass {
        @Override
        public Collection<Someclass> getCollection() {
            // TODO Auto-generated method stub
            return null;
        }
    }
    
        7
  •  0
  •   user290466 user290466    16 年前

    或许,你应该做些变通。

    看一看:

    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;
        }
    
    } 
    

    你可以这样收集:

    HolderClass<SomeSuperClass> holderClass = new HolderClass<SomeSuperClass>();
    holderClass.putSomeClass(new SomeClass());
    holderClass.putSomeClass(new SomeSuperClass());
    

    现在,当您调用getMyClasses()时,您将得到一些超类的集合

        8
  •  0
  •   Adam111p    9 年前

    是的,我们可以!

    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() ) );
    

    请测试一下

        9
  •  0
  •   Mike Nakis    5 年前

    解决方案

    static result 回来之前 结果 为了能够使用 @SuppressWarnings .

    /**
     * Casts a {@link Collection} to a {@link Collection} of an ancestral element type.
     *
     * @param collection the {@link Collection} to down-cast.
     * @param <T>        the required ancestral element type.
     *
     * @return the same {@link Collection} where the element type is the given ancestral type.
     */
    public static <T> Collection<T> downCast( Collection<? extends T> collection )
    {
        @SuppressWarnings( "unchecked" ) Collection<T> result = (Collection<T>)collection;
        return result;
    }
    

    class Ancestor {}
    class Descendant extends Ancestor {} 
    Collection<Descendant> descendants;
    Collection<Ancestor> ancestors = downCast( descendants );
    

    也适用于泛型:

    class Ancestor<T> {}
    class Descendant<T> extends Ancestor<T> {} 
    Collection<Descendant<T>> descendants;
    Collection<Ancestor<T>> ancestors = downCast( descendants );
    
        10
  •  -3
  •   Everyone    16 年前

    对于超类型。