2011-03-21 101 views
17
字段名

我被自己的領域努力組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

回答

53

有可能是可以做到這一點更簡單地庫,但它不是太難做手工:

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

4

類似的東西(我沒編譯)

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

你應該添加人的對象首先。 Java中的數組列表後,我們可以找回那些細節如下方式

公共無效addPerson的(){

ArrayList的presonList =新的ArrayList();

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

人OBJ = presonList.get(ⅰ);

//現在做的到這兒個別變量

}

}

1

在斯卡拉的東西,這已經是類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調用該方法。

11

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

26

使用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

1

您可以使用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正宗的貢獻。