Group by field name in Java

前端 未结 7 1818
迷失自我
迷失自我 2020-12-01 05:35

I\'m trying to group Java objects by their field, i.e Person.java

public class Person {
    String name;
    String surname;
    ....
}
相关标签:
7条回答
  • 2020-12-01 06:09

    something like that (i didn't compile)

    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);
    }
    
    0 讨论(0)
  • 2020-12-01 06:10

    Google Guava's Multimap does exactly what you need and much more, avoiding much boilerplate code:

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

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

    0 讨论(0)
  • 2020-12-01 06:14

    You can use Multimap and groupBy() from Eclipse Collections

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

    If you can't change the type of allPeople from List

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

    Note: I am a contributor to Eclipse Collections.

    0 讨论(0)
  • 2020-12-01 06:18

    There's probably a library that can do this more simply, but it's not too hard to do it manually:

    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");
    
    0 讨论(0)
  • 2020-12-01 06:19

    In Scala, this is a feature of the class List already:

    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[String,List[Person]] = Map((David,List(Person@1c3f810, Person@139ba37)), (Sue,List(Person@11471c6)), (Joe,List(Person@d320e4)))

    Since Scala is bytecode compatible to Java, you should be able to call that method from Java, if you include the scala-jars.

    0 讨论(0)
  • 2020-12-01 06:28

    Using java-8 with the Collectors class and streams, you can do this:

    Map<String, List<Person>> mapByName = 
        allPeople.stream().collect(Collectors.groupingBy(Person::getName));
    
    List<Person> allDavids = mapByName.getOrDefault("David", Collections.emptyList());
    

    Here I used getOrDefault so that you get an empty immutable list instead of a null reference if there is no "David" in the original list, but you can use get if you prefer to have a null value.

    Hope it helps! :)

    0 讨论(0)
提交回复
热议问题