London
London

Reputation: 15284

Group by field name in Java

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

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

So if I have n Person objects, what would be the easiest way to get all people name "David" into a map like Map<String, List<Person>> map;?

I found this on Google (but it doesn't compile), it seems to be the thing I'm looking for: http://www.anzaan.com/2010/06/grouping-objects-using-objects-property/

Upvotes: 17

Views: 31119

Answers (7)

Alexis C.
Alexis C.

Reputation: 93872

Using 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! :)

Upvotes: 28

Nikhil Nanivadekar
Nikhil Nanivadekar

Reputation: 1152

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.

Upvotes: 1

GFonte
GFonte

Reputation: 451

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

Upvotes: 11

user unknown
user unknown

Reputation: 36259

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.

Upvotes: 1

developer
developer

Reputation: 9478

First of all you should add objects of Person.java in the arraylist later we can get back those details in below manner

public void addPerson(){

ArrayList presonList = new ArrayList();

for( int i=0;i<=presonList.size() ; i++){

Person obj = presonList.get(i);

//now do the stuff of getting individual variable here

}

}

Upvotes: -1

Nazarii Bardiuk
Nazarii Bardiuk

Reputation: 4342

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

Upvotes: 4

Kaleb Brasee
Kaleb Brasee

Reputation: 51965

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

Upvotes: 58

Related Questions