从Set <type>到Set <typea> </typeb> </types>的PArsing

时间:2010-11-24 10:26:29

标签: java generics

我有一个奇怪的问题,我希望有人可以帮助我。 我正在使用Java。

我从方法中收到一个Set。这个TypeA正是我想要的,但我想为它增加一些功能,以增加代码的清洁度。

在C#中,我可以编写扩展方法,但我不认为Java有类似的东西,所以我想创建一个包含TypeA变量的新类型TypeB,并执行我想要的额外功能(某些东西)像包装/适配器)。但问题是:

我无法做到

Set<TypeB> mySet = myMethod();

Set<TypeB> mySet = (Set<TypeB>)myMethod();

什么是完美的将是那样的

Set<TypeB> mySet = new Set<TypeB>(myMethod());

但是Set是一个Java类型,所以我无法添加构造函数。

我怎么能这样做,我可以用干净的方式解析它? 如果我添加像

这样的方法
Set<TypeB> mySet = parse(myMethod());

我必须遍历myMethod中的所有项目,这不是很有效。

有没有比创建此方法更好的解决方案?

谢谢, 奥斯卡

3 个答案:

答案 0 :(得分:4)

如果您不是通过继承TypeA而是通过使用函数(静态方法)添加功能,那该怎么办:

所以而不是:

public class TypeB {
    TypeA self;
    public void Frobnicate(int foo) {...}
}

写:

public class TypeAUtils {
    public static void Frobnicate(TypeA self, int foo) {...}
}

C#扩展方法无论如何都只是这种技术的语法糖。

这是我最喜欢的设计模式之一。我把它称为“功能”,它被低估了。 :-P

如果你不能这样做(因此你也无法使用扩展方法),那么你必须向TypeA添加状态,在这种情况下你必须为每个对象分配更多的内存你的集合,这意味着你无法避免迭代。

答案 1 :(得分:2)

只有这样的smt

Set<TypeB> parse(Set<TypeA> old){
   Set<TypeB> res = new HashSet<TypeB>();
   for(TypeA a : old) res.add(new TypeB(a));
   return res;
}

或者创建自己的Set。

答案 2 :(得分:1)

修改

(根据OP下面的澄清评论修改。)

我们假设B有一个构造函数

    public B(A a) { ... }

创建B适应A实例。然后,从Set<B>创建Set<A>的最简单方法是:

    Set<A> aset = ...
    Set<B> bset = new HashSet<B>(aset.size());
    for (A a : aset) {
        bset.add(new B(a));
    }

Apache Commons Collections和Guava Collections包括可以将一个类的集合转换为另一个类的集合的基础结构,但是对于像这样简单的事情来说它们会有点过分。 (但如果你确实想要沿着那条路走下去,那么Guava会更好,因为API可以识别泛型。)