【问题标题】:Create a new list with values from fields from existing list使用现有列表中的字段值创建一个新列表
【发布时间】:2013-12-03 21:46:48
【问题描述】:

假设有一个类:

class Person
{
   String name;
   int age;
   City location;
}

是否有一些库可以让我创建一个字符串列表,其中包含列表中的每个名称 一行中的人,而不是创建一个新列表并遍历另一个列表?

类似:

List<Person> people = getAllOfThePeople();
List<String> names = CoolLibrary.createList("name", people);

而不是:

List<Person> people = getAllOfThePeople();
List<String> names = new LinkedList<String>();
for(Person person : people)
{
    names.add(person.getName());
}

【问题讨论】:

  • 如果只有 Java 本身有 LINQ 就好了。不,这是不可能的。也许 Java 8 支持它,但它肯定不是在那之前。当然可以通过反射实现,但没有内置查询选项。
  • 显得过于具体,但您可以使用反射和泛型编写一个以使输出强类型化..

标签: java list collections field


【解决方案1】:

您可以将 Java 8 与 lambda expressions 一起使用:

List<String> listNames = people.stream().map(u -> u.getName()).collect(Collectors.toList());

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

public class Test {
  public static void main(String args[]){
    List<Person> people = Arrays.asList(new Person("Bob",25,"Geneva"),new Person("Alice",27,"Paris"));
    List<String> listNames = people.stream().map(u -> u.getName()).collect(Collectors.toList());
    System.out.println(listNames);
  }
}
class Person
{
   private String name;
   private int age;
   private String location;

  public Person(String name, int age, String location){
    this.name = name;
    this.age = age;
    this.location = location;
  }

  public String getName(){
    return this.name;
  }

}

输出:

[Bob, Alice]

演示here.


或者,您可以定义一个方法,将您的列表作为参数,以及您要为该列表的每个元素应用的函数:
public static <X, Y> List<Y> processElements(Iterable<X> source, Function <X, Y> mapper) {
    List<Y> l = new ArrayList<>();
    for (X p : source) 
        l.add(mapper.apply(p));
    return l;
}

那就做吧:

List<String> lNames = processElements(people, p -> p.getName()); //for the names
List<Integer> lAges = processElements(people, p -> p.getAge()); //for the ages
//etc.

如果您想按年龄分组,Collectors 类提供了不错的实用程序(示例):

Map<Integer, List<Person>> byAge = people.stream()
                                         .collect(Collectors.groupingBy(Person::getAge));

【讨论】:

    【解决方案2】:

    您可以使用Guava 库(我认为最终的Java 库,无论如何您都应该使用它)来做一些小技巧:

    class Person
    {
       String name;
       int age;
       City location;
    
      public static final Function<Person, String> getName = new Function<Person, String>() {
        public String apply(Person person) {
          return person.name;
        }
      }
    }
    
    
    List<Person> people = getAllOfThePeople();
    List<String> names = FluentIterable.from(people).transform(Person.getName).toList();
    

    诀窍是在 Person 类中定义 getName public static Function

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 2015-04-19
      • 2019-11-29
      • 2019-12-27
      相关资源
      最近更新 更多