从对象列表的getter创建值列表

时间:2012-11-14 06:24:35

标签: java list

好吧,让我说我有一个非常简单的课程,例如

public class Baby {
   private String Name = "alf";
   public String getName() {
      return Name;
   }
}

现在我想知道什么。鉴于Baby的列表,在Java中是否有任何更简单/更酷/更短的方式来创建婴儿名字的阵列/ arraylist而不是简单地循环遍历所有婴儿并将他们的名字添加到新列表中?相当于:

ArrayList<Baby> babies = new ArrayList<Baby>();
/* some code adding a bunch of babies to the arraylist */

ArrayList<String> names = new ArrayList<String>();
for (Baby b : babies) {
  names.add(b.getName());
}

...但更酷。知道我的意思吗?

4 个答案:

答案 0 :(得分:3)

您可以使用Guava's Lists.transform

Function<Baby, String> getBabyNameFunction = new Function<Baby, String>() {
    @Override
    public String apply(Baby baby) {
        return baby.getName();
    }
};

List<String> babyNames = Lists.transform(babies, getBabyNameFunction);

这里的关键区别在于babyNames是原始列表的视图,其中转换被懒惰地执行。来自文档:

  

该函数被懒惰地应用,在需要时调用。这是必要的   对于返回的列表是视图,但它表示该函数   将被多次应用于批量操作,如   List.contains(java.lang.Object)List.hashCode()。为了这个   表现不错,功能要快。避免懒惰评估时   返回的列表不需要是视图,复制返回的列表   进入您选择的新列表。

显然,实现Function的语法相当冗长 - 除非是lambda,否则就是Java。我通常将常用函数保留为常量,以避免在调用站点出现混乱和重新实例化:

public class Baby {

    ...

    public static class Functions {

        private static final Function<Baby, String> GET_NAME =
                new Function<Baby, String>() {
                    @Override
                    public String apply(Baby baby) {
                        return baby.getName();
                    }
                };

        private Functions() { }

        public static Function<Baby, String> getName() {
            return GET_NAME;
        }
    }
}

是的,这是更多的代码,但它隐藏起来,更易于维护。然后在通话现场:

List<String> babyNames = Lists.transform(babies, Baby.Functions.getName());

答案 1 :(得分:1)

使用GS Collections,你有几种方法可以做到这一点。您可以使用名为FastList的ArrayList的插件替换。

MutableList<Baby> babies = FastList.newList();
/* some code adding a bunch of babies to the fastlist */

MutableList<String> names = babies.collect(new Function<Baby, String>() {
    public String valueOf(Baby baby) {
        return baby.getName();
    }
});

或者您可以将ArrayList与ListIterate实用程序类一起使用。

ArrayList<Baby> babies = new ArrayList<Baby>();
/* some code adding a bunch of babies to the arraylist */

List<String> names = ListIterate.collect(babies, new Function<Baby, String>() {
    public String valueOf(Baby baby) {
        return baby.getName();
    }
});

如果您不关心结果顺序,但想要允许重复,则可以使用Bag。

MutableList<Baby> babies = FastList.newList();
/* some code adding a bunch of babies to the fastlist */

MutableBag<String> names = babies.collect(new Function<Baby, String>() {
    public String valueOf(Baby baby) {
        return baby.getName();
    }
}, HashBag.<String>newBag());

int numberOfBabiesNamedXYZ = names.occurrencesOf("XYZ");

如果您反复使用此功能,您可能希望将它作为常量放在Baby类上。

注意:我是GS Collections的开发人员。

答案 2 :(得分:0)

嗯......简单地说,不。

假设你正在寻找像

这样的东西
ArrayList<String> names = babies.getName();

在Java中没有类似的东西。

但是,您可以为自己创建一个新课程:

public class BabyNameifier {

    public BabyNameifier(){}

    public ArrayList<String> Nameify(ArrayList<Baby> babies) {
        ArrayList<String> names = new ArrayList<String>();
        for (Baby b : babies) {
            names.add(b.getName());
        }
        return names;
    }
}

那样,你可以稍后说:

ArrayList<Baby> babies = new ArrayList<Baby>();
/* some code adding a bunch of babies to the arraylist */

BabyNameifier babyNameifier = new BabyNameifier();
ArrayList<String> names = babyNameifier.Nameify(babies);

这将创造一种系统地检索世界所知的婴儿名字的最酷方式。

答案 3 :(得分:0)

您想要 cool 方式吗?如果您了解Spring框架,那么您很幸运!

在applicationContext.xml中,写下这样的内容:

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="babyList" class="com.babies.BabyList">

    <property name="babyLists">
        <list>
            <bean class="com.babies.Baby">
                <property name="name" value="alice" />
            </bean>
            <bean class="com.babies.Baby">
                <property name="name" value="bob" />
            </bean>
            <bean class="com.babies.Baby">
                <property name="name" value="trudy" />
            </bean>
        </list>
    </property>
</bean>

 </beans>

以下是普通Java中的代码

package com.babies;

 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;

  public class Main  {
      public static void main( String[] args ) {
          ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

          BabyList babyList = (BabyList)context.getBean("babyList");
          System.out.println(babyList);

    }
  }

现在,只要您想从列表中添加/删除任何名称,就可以编辑applicationContext.xml中的列表。无需对所有内容进行硬编码。

您可以从以下链接中详细了解Spring框架集合:http://www.mkyong.com/spring/spring-collections-list-set-map-and-properties-example/

或者,如果您只是想了解有关Spring的更多信息,那么这是一个很好的起点: http://www.mkyong.com/tutorials/spring-tutorials/