Java扩展ArrayList<Dummy>函数

4

假设我有

class Dummy {
    String a, b;
    public Dummy(String a, String b) {
        this.a = a;
        this.b = b;
    }
    public String toString(){
        return a+b;
    }
    public String getA() {
        return a;
    }
    public String getB() {
        return b;
    }

}

i would like to have

List<Dummy> myList = new ArrayList<Dummy>() {{
     add(new Dummy("test", ""));
     add(new Dummy("boo", "o"));
}};

System.out.println( myList.toString());
System.out.println( myList.getAs());  //should return ["test", "boo"]
System.out.println( myList.getBs());//should return ["", "o"]

如果你明白我的意思

可能需要创建一个继承ArrayList<Dummy>类的类?

编辑:

看起来就像那样不错

class Dummy {
    String a, b;
//...
    public static String toAString(List<Dummy> l){
       String s="";
       for (Dummy d : l){
           s+=d.a;
       }
       return s;
    }
}

编辑2:

我在Dummy中只有两个字符串,使用ArrayList<String []>是否更好?从内存的角度考虑。


是的,我非常确定那就是你必须要做的。 - Ian McLaird
可能更容易的方法是编写一个包装ArrayList的方法,而不是直接扩展它。 - Louis Wasserman
@Louis,你的意思是有两种方法:public String toAString(ArrayList<Dummy> list){在这里执行循环}? - user1125394
好的,要么做一个循环,要么返回某种视图,但是没错。 - Louis Wasserman
@ciril,有几位朋友提供了可行的答案。如果其中任何一个可接受,也许您可以点赞和/或接受一些答案。 - Kevin Welker
谢谢你的回答,missingfaktor是我正在寻找的最接近的,期待1年后的Java8。 - user1125394
6个回答

2

定义与getAgetB相应的一等函数。我正在使用Guava中的Function

class Dummy {
    String a, b;
    public Dummy(String a, String b) {
        this.a = a;
        this.b = b;
    }
    public String toString(){
        return a+b;
    }
    public String getA() {
        return a;
    }
    public String getB() {
        return b;
    }
    public static Function<Dummy, String> getA = new Function<Dummy, String>() {
      public String apply(Dummy d) {
        return d.a;
      }
    }
    public static Function<Dummy, String> getB = new Function<Dummy, String>() {
      public String apply(Dummy d) {
        return d.b;
      }
    }
}

这是你可以使用它的方法:(下面的Iterables也来自Guava)。
List<Dummy> myList = new ArrayList<Dummy>() {{
     add(new Dummy("test", ""));
     add(new Dummy("boo", "o"));
}};

System.out.println( myList.toString());
System.out.println( Iterables.transform(myList, Dummy.getA)); // returns ["test", "boo"]
System.out.println( Iterables.transform(myList, Dummy.getB)); // returns ["", "o"]

这是一个合理的担忧。幸运的是,所需的功能很容易自己实现。(大约10行代码。) - missingfaktor
很好,Function <Dummy, String> 的意思是它接受一个 Dummy 并返回一个 String?太糟糕了,guava 不能使用默认的 getters 来实现。 - user1125394
@ciril,是的,那正是它的意思。 - missingfaktor
@ciril,感谢Java 8,您不必显式定义这些函数对象。myList.map(Dummy::getAs)就可以解决问题了。map是新集合API中的一个方法,而Dummy::getAs则提供了所谓的方法引用。 - missingfaktor
你确定它不会是 myList.map(Dummy::getA)(没有's)吗? - user1125394
显示剩余2条评论

2
在Java 8之前,您可以使用Guava等函数式编程API之一,如下所示:
Function<Dummy, String> getAFunc = new Function<Dummy, String> {
    @Override
    public String apply(Dummy dummy) {
        return dummy.getA();
    }
}

Function<Dummy, String> getBFunc = new Function<Dummy, String> {
    @Override
    public String apply(Dummy dummy) {
        return dummy.getB();
    }
}

System.out.println( Lists.transform(myList, getAFunc) );
System.out.println( Lists.transform(myList, getBFunc) );

同意这很丑陋和啰嗦,这也是Guava团队所说的滥用函数式语言使他们哭泣的原因之一。
但是,请稍等,有希望,并且有一种方法可以使用开源的Funcito免责声明:我是主要作者)使此代码更加优雅、更短、更适用于任何类似情况。
现在,你只需要简单地编写:
Function<Dummy, AType> getAFunc = functionFor( callsTo(Dummy.class).getA() );
Function<Dummy, BType> getBFunc = functionFor( callsTo(Dummy.class).getB() );

System.out.println( Lists.transform(myList, getAFunc) );
System.out.println( Lists.transform(myList, getBFunc) );

简述:使用Funcito来组合函数是简洁的关键。即使A和B不是字符串,也可以使用它,如我所示的例子。现在,您可以使用Funcito来生成包装适当方法的函数,用于除Dummy以外的任何类型,并且对于具有getter方法的任何数量的字段。如果您喜欢,Funcito还将与一些其他功能API(而非Guava)一起使用。请注意,上面使用了Guava的导入和Funcito的静态导入。

1

是的,你说得对,你需要扩展ArrayList来实现这个。


0
      List<Dummy> myList = new ArrayList<Dummy>() 
      myList.add(new Dummy("test", ""));     
      myList.add(new Dummy("boo", "o")); 


                     for(Dummy dumdum : myList) {
                     System.out.println(dumdum.getA() + " " + dumdum.getB());
                      }

这是您要找的吗,还是我误解了您的问题?


0

使用组合而不是继承..............

考虑同一包中的所有类。

虚拟类:

class Dummy {
    String a, b;
    public Dummy(String a, String b) {
        this.a = a;
        this.b = b;
    }
    public String toString(){
        return a+b;
    }
    public String getA() {
        return a;
    }
    public String getB() {
        return b;
    }

}

测试类:已编辑

public class Test{
 Test t = new Test();                   
 List<Dummy> myList = new ArrayList<Dummy>();
 public static void main(String[] args){
 t.myList.add(new Dummy("test", ""));
 t.myList.add(new Dummy("boo", "o"));
for (Dummy d : t.myList)
{
  System.out.println(d.toString());
  System.out.println(d.getA());  
  System.out.println(d.getB()); 
  }
 } 
}

现在试一下......它按照你想要的方式工作了......对于错误我很抱歉... - Kumar Vivek Mitra
是的,做同样的事情,我需要从 myList 调用一个函数,问题是我会多次调用这些函数,因此循环会执行多次... - user1125394

0
扩展ArrayList很快就变得不可行了,因为你最终需要一个MoronArrayList、一个GeniusArrayList、一个DummyHashMap、一个DummyQueue等等...
@missingfaktor建议的Guava库是一个选择。如果这确实经常需要,另一个选择是将实用方法放入“Dummy”类中,例如:
public static String toAStrings(Collection<Dummy> collection) {
   StringBuilder sb = new StringBuilder;
   boolean firstTime = true;
   for (Dummy dummy : collection) {
      if (!firstTime )
         sb.append(",");
      firstTime = false;
      sb.append(dummy.getA());
   }

   return sb.toString();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接