0

我有一个名为 DataSet 的类,它有各种构造函数,每个构造函数都指定不同类型的变量。它可能看起来有点像这样:

public class DataSet
{
    private HashSet Data;


    public DataSet( DataObject obj )
    {
        Data = new <DataObject>HashSet();
        Data.add( obj );
    }

    public DataSet( ObjectRelationship rel )
    {
        Data = new <ObjectRelationship>HashSet();
        Data.add( rel );
    }
    // etc.

注意:由于部分不完整(我现在正在构建),我尚未测试该代码。

在我当前正在构建的函数中getDataObjects(),我需要返回该集合表示的所有 DataObject 对象。对于初始化类的 HashSet 的构造函数,Data其类型不是DataObject(例如上述ObjectRelationship),显然不会有任何 DataObjects 存储在其中。在这种情况下,我需要能够检测 HashSet 'Data' 的启动类型(例如,判断它是否是 'ObjectRelationship',我的意思是)。我该怎么做呢?



tl;dr:我如何判断在我的代码中启动集合(在本例中为 HashSet)的类型(例如使用“if”或“switch”语句或其他内容)?

4

8 回答 8

4

听起来你想让整个类通用——在类的声明中添加一个模板参数,并使用该模板参数为类型定义你的 HashSet 和检索函数。

不过,我现在是一个 .Net 人,所以我不能给你 Java 语法,但是使用 C#语法它看起来像这样:

public class DataSet<T>
{
    private Set<T> Data;

    public DataSet( T obj )
    {
        Data = new HashSet<T>();
        Data.add( obj );
    }

    public Iterator<T> getDataObjects()
    {
        return Data.iterator;
    }
}
于 2008-12-26T15:12:42.690 回答
1

您可以从集合中获取一个对象并验证其类型。

或者你可以有多个集合来包含不同的类型。

或者你可以有一个 Class 类型的实例变量作为实例变量的鉴别器。

或者您可以使用最后一种技术为 HashSet 创建一个代理对象。

于 2008-12-26T14:56:31.583 回答
1

听起来您的设计需要重新考虑。

另外,要明确泛型;您无法在运行时访问该类型。type 参数仅用于编译时检查,并且在运行时完全消失(类型擦除)。

于 2008-12-26T18:08:41.570 回答
1

您可以使用地图到集合

HashMap <Class<?>, HashSet<Object>> data;
HashSet temp = data.get(DataObject.class);
if(temp == null)
{
   temp = new HashSet();
   data.put(DataObject.class, temp);
}
temp.add(obj);

然后,您将获得两全其美。

于 2008-12-26T16:45:04.577 回答
0

这个类提供了什么 CachedRowSet 没有?

抱歉,我不认为这是一个很好的抽象。如果我是你们团队的一员,我不会使用它。

你的语法对我来说也不正确。IntelliJ 同意我的观点:它不会编译。

这样做:

import java.util.HashSet;
import java.util.Set;
import java.util.Arrays;

public class DataSet
{
    private Set<DataObject> data;


    public DataSet(DataObject obj)
    {
        this.data = new HashSet<DataObject>();
        data.add(obj);
    }

    public DataSet(DataObject[] objs)
    {
        data = new HashSet<DataObject>();
        data.addAll(Arrays.asList(objs));
    }
    // etc.
}

仍然是一个糟糕的抽象。重新考虑一下。

于 2008-12-26T14:58:21.767 回答
0

您可以向数据集类添加一个属性(枚举值、布尔值或类型),指定用于初始化哈希集的类型。

在适当的构造函数中设置属性。这允许您绕过从集合中获取元素来检查其类型。

伪代码:

public class DataSet
{
private HashSet Data;
private Type _iw = null;
public Type InitializedWith { return _iw; }

public DataSet(DataObject)
{
...
_iw = typeof(DataObject);
}

public DataSet(ObjectRelationship)
{
...
_iw = typeof(ObjectRelationship)
}
于 2008-12-26T15:05:41.580 回答
0

我将遵循 duffymo 的建议并使用更好的抽象。我将为我计划使用的每种特定类型创建多个类(每个实现一个公共接口),这样我就可以绕过这个愚蠢的问题。

在创建每个正确类型的 DataSet 对象的过程中,它会增加一点点开销,但我想这就是它的方式。

于 2008-12-26T16:22:44.390 回答
0

我不知道 DataObject 在 Object 之外给你什么。

我认为针对您的问题的面向对象的方法将使用反映您感兴趣的领域的类(例如,发票、客户等)。持久层将隐藏持久性细节。

实现此目的的常用方法是使用数据访问对象,它在 Java 中可能如下所示:

public interface GenericDao<T>
{
    T find(Serializable id);
    List<T> find();
    void save(T obj);
    void update(T obj);
    void delete(T obj);
}

现在您处理的是对象,而不是带有关系数据库味道的东西。所有的 CRUD 细节都隐藏在 DAO 界面后面。

于 2008-12-26T17:38:08.340 回答