2012-11-14 34 views
5

好吧,让我们说我有一个非常简单的类,例如创建来自对象列表的获得者的值列表

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

现在我想知道的。给出一份Baby's的列表,Java中是否有任何更酷/更酷/更短的方式来创建婴儿名称的数组/列表列表,而不是简单地遍历所有婴儿并将其名称添加到新列表中?这相当于:

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()); 
} 

...但冷却器。知道我的意思吗?

+2

*冷却器*?有可能。更可读和易懂:几乎没有。在我们终于有lambda表达式(和方法句柄)之前,我们将不能写得比这更简洁。 –

+0

@JoachimSauer在java中将会引入'lambdas'作为官方文档的一部分吗? –

+0

@ ZagorulkinDmitry Java 8应该包括它。但是,再一次,它最初是为了Java 7:|而设计的 – amit

回答

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); 

这将创造只是最酷的方式来系统检索世界所知的婴儿名称。

+0

啊哈!其实,我想象的是类似于你的第一个陈述......'babies.getNames()'; :P啊,我可以做梦。 编辑:还是习惯了这种“输入方式送!”特征。我喜欢你的想法,作为任何超级漂亮的替代品 - 后面的代码看起来很酷! – user891876

3

你可以使用Guava'sLists.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语法是相当冗长 - 这就是Java的你,直到lambda表达式。我通常将常用的功能为常数,以避免混乱和重新实例在调用点:

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

大声笑是啊,这是比我最初寻找更详细,但该死的酷!我从来没有听说过这些番石榴列表,这正是我寻找的漂亮代码。谢谢! – user891876

+0

如果你认为现在很酷,一旦我们*不要*有Lambda表达式&CO这将是短'名单 babyNames = Lists.transform(婴儿,婴儿#的getName);'(语法可能会略有不同,但像这样)。 –

0

你想冷却器办法做到这一点?如果你了解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/

或者,如果你只是想了解更多关于春天,这里是一个很好的起点: http://www.mkyong.com/tutorials/spring-tutorials/

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(); 
    } 
}); 

或者你可以使用与ListIterate实用工具类ArrayList中。

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正宗开发商。