Reputation: 86
I have an ArrayList
that looks like this:
ArrayList<TravelData> listOfTravels;
and TravelData
object contains the following elements
int id;
String groupName;
String guideName;
This is how I initialize the arrayList:
listOfTravels.add(new TravelData(1,"group a", "Ross"));
listOfTravels.add(new TravelData(2,"group a", "Chandler"));
listOfTravels.add(new TravelData(3,"group a", "Monica"));
listOfTravels.add(new TravelData(4,"group b", "Phoebe"));
listOfTravels.add(new TravelData(5,"group b", "Rachel"));
listOfTravels.add(new TravelData(6,"group c", "Joey"));
listOfTravels.add(new TravelData(7,"group c", "Rachel"));
listOfTravels.add(new TravelData(8,"group d", "Chandler"));
I want to get the top 3 most common groups and guides on that list. In this example:
Top 3 groups: "group a", "group b", "group c"
Top 3 guides: "Rachel", "Chandler", "Ross"
(The third place of guides could be anyone else because Ross, Monica, Phoebe and Joey have the same appearance count).
I found good answers like how to get the most common element in a list but it's only good for ArrayList
of integers and shows only the first most common element.
Upvotes: 0
Views: 903
Reputation: 748
This is a good use case for streams. The idea is, to first transform the List<TravelData>
to Map<String, Integer>
of group to number of guides (or guide to number of groups) and then sort that map by the numbers, take only the map's keys (groups/guide) and limit it to the first three elements.
I am assuming that TravelData has the methods String getGroup()
and String getGuide()
:
Using Java 11 type inference in the example
final comparator = Comparator.comparing(Map::getValue)
.reversed();
final top3Groups = listOfTravels.stream().collect(Collectors.groupingBy(TravelData::getGroup(),
Collectors.counting())
.entrySet()
.stream().sorted(comparator)
.map(Map::getKey)
.limit(3)
.collect(Collectors.toList());
final top3Guides = listOfTravels.stream().collect(Collectors.groupingBy(TravelData::getGuide(),
Collectors.counting())
.entrySet()
.stream().sorted(comparator)
.map(Map::getKey)
.limit(3)
.collect(Collectors.toList());
Upvotes: 0
Reputation: 1829
Here's my solution with Streams.
// comparator for reverse sorting
Comparator<Map.Entry<String, Long>> reversed = Map.Entry.comparingByValue();
Comparator<Map.Entry<String, Long>> entryComparator = Collections.reverseOrder(reversed);
List<String> collect = listOfTravels.stream()
.collect(Collectors.groupingBy(TravelData::getGuideName, Collectors.counting()))
.entrySet()
.stream()
.sorted(entryComparator)
.map(Map.Entry::getKey)
.limit(3)
.collect(Collectors.toList());
System.out.println(collect);
Upvotes: 0
Reputation: 273
Try this it will help you.
public class TravelData {
int id;
String groupName;
public String getGroupName() {
return groupName;
}
public String getGuideName() {
return guideName;
}
String guideName;
public TravelData(int id, String groupName, String guideName) {
this.id = id;
this.groupName = groupName;
this.guideName = guideName;
}
public static void getcommonGroups(ArrayList<TravelData> list){
Map<String, Integer> wordMap = new HashMap<String, Integer>();
for(TravelData td:list){
if(wordMap.containsKey(td.getGroupName())){
wordMap.put(td.getGroupName(), wordMap.get(td.getGroupName())+1);
} else {
wordMap.put(td.getGroupName(), 1);
}
}
List<Map.Entry<String, Integer>> sortedList = sortByValue(wordMap);
for(Map.Entry<String, Integer> entry:sortedList){
System.out.println(entry.getKey()+" ===="+entry.getValue());
} }
public static List<Map.Entry<String, Integer>> sortByValue(Map<String, Integer>
wordMap) {
Set<Map.Entry<String, Integer>> set = wordMap.entrySet();
List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(set);
Collections.sort( list, new Comparator<Map.Entry<String, Integer>>()
{
public int compare( Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 )
{
return (o2.getValue()).compareTo( o1.getValue() );
}
} );
return list;
}
public static void main(String args[]){
ArrayList<TravelData> listOfTravels=new ArrayList() ;
listOfTravels.add(new TravelData(1,"group a", "Ross"));
listOfTravels.add(new TravelData(2,"group a", "Chandler"));
listOfTravels.add(new TravelData(3,"group a", "Monica"));
listOfTravels.add(new TravelData(4,"group b", "Phoebe"));
listOfTravels.add(new TravelData(5,"group b", "Rachel"));
listOfTravels.add(new TravelData(6,"group c", "Joey"));
listOfTravels.add(new TravelData(7,"group c", "Rachel"));
listOfTravels.add(new TravelData(8,"group d", "Chandler"));
getcommonGroups(listOfTravels);
}}
Upvotes: 2
Reputation: 48407
You could create a hashMap
structure for groups
where the key
will be groupName
and the value will be the number of occurences.
Then, just sort
the hashMap
structure by value descending
and get the results.
Upvotes: 1