集团通过在Java中

问题描述:

字段名

我被自己的领域努力组Java对象,即Person.java集团通过在Java中

public class Person { 
    String name; 
    String surname; 
    .... 
} 

所以,如果我有ň Person对象,这将是最简单的方法将所有人的姓名“大卫”变成像Map<String, List<Person>> map;这样的地图?

我发现这对谷歌(但它不会编译),这似乎是我在寻找的东西: http://www.anzaan.com/2010/06/grouping-objects-using-objects-property/

+2

编译错误说什么? – MBU 2011-03-21 23:50:18

有可能是可以做到这一点更简单地库,但它不是太难做手工:

List<Person> allPeople; // your list of all people 
Map<String, List<Person>> map = new HashMap<String, List<Person>>(); 
for (Person person : allPeople) { 
    String key = person.getName(); 
    if (map.get(key) == null) { 
     map.put(key, new ArrayList<Person>()); 
    } 
    map.get(key).add(person); 
} 

List<Person> davids = map.get("David"); 
+3

你快速+1 – 2011-03-21 23:57:27

+0

但问题是关于一个通用的解决方案,你只需指定一个类的名称,所以你可以通过一个persons:= Person列表,并将“name”作为该字段的名称,并且该功能将完成剩下的工作。在下一个案例中,您会传递一个汽车列表和一个字段名称“制造商”。在scala中,你只需在列表中调用persons.filter(p => p.name ==“David”)或组。 – 2011-03-22 01:27:40

+4

可怜的Java人......他们永远不会知道LINQ的乐趣:) – 2012-07-25 16:58:13

类似的东西(我没编译)

void addPerson(Person p, Map<String, List<Person>> map){ 
    ArrayList<Person> lst = map.get(p.name); 
    if(lst == null){ 
    lst = new ArrayList<Person>(); 
    } 
    lst.add(p); 
    map.put(p.name, lst); 
} 
... 
for(Person p:personsCollection>){ 
    addPerson(p, map); 
} 

你应该添加人的对象首先。 Java中的数组列表后,我们可以找回那些细节如下方式

公共无效addPerson的(){

ArrayList的presonList =新的ArrayList();

对(INT I = 0;我< = presonList.size();我++){

人OBJ = presonList.get(ⅰ);

//现在做的到这儿个别变量

}

}

在斯卡拉的东西,这已经是类List的特点:

class Person (val name: String, val surname: String ="Smith") 
val li = List (new Person ("David"), new Person ("Joe"), new Person ("Sue"), new Person ("David", "Miller")) 
li.groupBy (_.name) 

res87: scala.collection.immutable.Map [Str (Joe,List(Person @ d320e4))), = Map((David,List(Person @ 1c3f810,Person @ 139ba37)), (Sue,List(Person @ 11471c6)),

由于Scala与Java的字节码兼容,如果包含scala-jar,您应该能够从Java调用该方法。

Google Guava的Multimap之不正是你所需要的以及更多,避免很多样板代码:

ListMultimap<String, Person> peopleByFirstName = ArrayListMultimap.create(); 
for (Person person : getAllPeople()) { 
    peopleByFirstName.put(person.getName(), person); 
} 

来源:http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap

+1

一个非常有用的事实是告诉人们在结果上调用'asMap()'。 'keys()','entries()'和'values()'似乎并不像你期望的那样。 – 2013-07-29 23:31:07

使用Collectors类和streams,你可以这样做:

Map<String, List<Person>> mapByName = 
    allPeople.stream().collect(Collectors.groupingBy(Person::getName)); 

List<Person> allDavids = mapByName.getOrDefault("David", Collections.emptyList()); 

这里我用getOrDefault,以便在原始列表中没有“David”的情况下获得一个空的不可变列表,而不是null参考,但如果您希望具有null值,则可以使用get

希望它有帮助! :)

+0

是否可以不使用getter,而是直接使用字段名称? – 2015-11-12 12:13:31

+1

@ ZhangMeng是的,在这种情况下,您可以使用lambda'p - > p.name',假设您可以访问'name'字段。 – 2015-11-12 13:14:37

您可以使用MultimapgroupBy()Eclipse Collections

MutableList<Person> allPeople = Lists.mutable.empty(); 
MutableListMultimap<String, Person> multimapByName = allPeople.groupBy(Person::getName); 

如果你不能从List

List<Person> allPeople = new ArrayList<>(); 
MutableListMultimap<String, Person> multimapByName = 
    ListAdapter.adapt(allPeople).groupBy(Person::getName); 

注allPeople的类型而改变:我到Eclipse正宗的贡献。