Java - 将泛型用于多种类型

时间:2014-08-15 13:13:22

标签: java generics

我有以下DataSet类,我们持有任何类型的对象。主要是将对象从服务器传输到客户端。 contents变量可以包含任何可序列化对象。它可以是自定义编写的类对象或java类,如IntegerString等。

我试图将其转换为泛型。我们应该如何同时将其转换为Generics,我想确保我不必更改所有包含的对象类代码,因为我们甚至使用String和{{ 1}}内容中的类。

我简化了课程,只展示了一些相关的领域和方法。

Integer

感谢您的提示回复。但是,在回顾下面的三个答案之后,我觉得我没有把这个问题正确地传达出去。

为了实现我想要的方式,如果我调用dataset.getObjects(E类型),我应该得到一个E类型的向量。我不应该投入(Vector)。因为我希望内容包含import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.Serializable; import java.util.Hashtable; import java.util.Vector; public class DataSet implements Serializable, PropertyChangeListener{ Hashtable contents = new Hashtable(); @Override public void propertyChange(PropertyChangeEvent arg0) { // TODO Auto-generated method stub } public void addObject(Object obj){ Vector vector = (Vector)contents.get(obj.getClass()); if (vector == null){ vector = new Vector(); vector.add(obj); contents.put(obj.getClass(), vector); } } public Vector getObjects(Class objType){ if (contents.contains(objType)){ return (Vector)contents.get(objType); } else{ return new Vector(); } } } Class<E>个键值对。如果我们能做到这一点,那么我只能说这是Vector<E>

safe

3 个答案:

答案 0 :(得分:2)

首先,远离班级Vector,它已经过时了;请改用ArrayList

这是一种存储异构对象的简单方法,同时在检索对象时避免显式转换。我确信你可以将这个模型应用到你的解决方案中。

更新,感谢Paul Bellora的建议。

public class DataSet { 

    private Map<Class<?>, List<?>> contents;

    public DataSet(){
       contents = new HashMap<Class<?>, List<?>>();  
    } 

    @SuppressWarnings(value = { "unchecked" })
    public <T> void addObject(Class<T> klass, T object){
        List<T> objectsList = (List<T>)contents.get(klass);
        if (objectsList == null){
            objectsList = new ArrayList<T>();            
            contents.put(klass, objectsList);
        }
        objectsList.add(object);
    }

    @SuppressWarnings(value = { "unchecked" })
    public <T> List<T> getObjects(Class<T> klazz) {
        return contents.containsKey(klazz) ? 
                contents.get(klazz) : Collections.EMPTY_LIST;
    }

    public static <S, T extends Iterable<S>> void print(T list){
        for (Object element : list){
            System.out.println(element);
        }
    }

    public static void main(String[] o){
       DataSet ds = new DataSet();
       ds.addObject(String.class, "save the earth!");
       ds.addObject(String.class, "firing now!");       
       ds.addObject(Integer.class, new Integer(100));
       ds.addObject(Boolean.class, new Boolean(true));

       print(ds.getObjects(String.class));
       print(ds.getObjects(Boolean.class));
       print(ds.getObjects(Integer.class));      
    }
 }

希望它有所帮助。

答案 1 :(得分:0)

也许这就足够了:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Map;
import java.util.List;

public class DataSet implements Serializable, PropertyChangeListener{

    Map<Class<?>, Vector<Serializable>> contents = new HashMap<Class<?>, Vector<Serializable>>();

    @Override
    public void propertyChange(PropertyChangeEvent arg0) {
        // TODO Auto-generated method stub
    }

    public void <T extends Serializable> addObject(T obj){
        Vector<T> vector = (Vector<T>)contents.get(obj.getClass());
        if (vector == null){
            vector = new Vector<T>();
            contents.put(obj.getClass(), vector);
        }
        vector.add(obj);
    }

    public <T extends Serializable> Vector<T> getObjects(Class<T> objType){
        if (contents.contains(objType)){
            return (Vector<T>)contents.get(objType);
        }
        else{
            return new Vector<T>();
        }
    }
}

我已编辑过原帖。实际上,正如Duncan在他的评论中指出的那样,DataSet结构本身并不具有通用性。尽管如此,一些泛型仍然可以添加一些语法糖以试图避免投射

答案 2 :(得分:0)

如果我没有记错,您的Hashtable 内容变量会将Serializable对象的类作为键,将Serializable Vector列表作为值

   import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.io.Serializable;
    import java.util.Hashtable;
    import java.util.Vector;

    public class DataSet implements Serializable, PropertyChangeListener{

        Hashtable<Class,Vector<Serializable> contents = new Hashtable<Class,Vector<Serializable>();

        @Override
        public void propertyChange(PropertyChangeEvent arg0) {
            // TODO Auto-generated method stub

        }

        public void addObject(Serializable obj){

            Vector<Serializable> vector = contents.get(obj.getClass());
            if (vector == null){
                vector = new Vector<Serializable>();
                vector.add(obj);
                contents.put(obj.getClass(), vector);
              }
            else{
              vector.add(obj);
               }
        }

        public Vector<Serializable> getObjects(Class objType){
            if (contents.contains(objType)){
                return (Vector<Serializable>)contents.get(objType);
            }
            else{
                return new Vector<Serializable>();
            }
        }
    }