【问题标题】:Java - Get most common elements in arrayList of ObjectJava - 获取对象的arrayList中最常见的元素
【发布时间】:2020-01-24 11:35:04
【问题描述】:

我有一个ArrayList,看起来像这样:

ArrayList<TravelData> listOfTravels;

而TravelData 对象包含以下元素

int id;
String groupName;
String guideName;

这就是我初始化数组列表的方式:

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

我想获得该列表中最常见的 3 个组和指南。 在这个例子中:

Top 3 groups: "group a", "group b", "group c"
Top 3 guides: "Rachel", "Chandler", "Ross"

(向导的第三名可能是其他任何人,因为罗斯、莫妮卡、菲比和乔伊的出场次数相同)。

我找到了像 how to get the most common element in a list 这样的好答案,但它只适用于整数的 ArrayList,并且只显示第一个最常见的元素。

【问题讨论】:

  • 在链接的问答中,查看collect(Collectors.groupingBy(TravelDate::getGroupName, Collectors.counting())),然后按值排序以获得相应的值。同样适用于TravelDate::getGuideName。
  • 您的解决方案是什么。到目前为止你尝试了什么?请用您的解决方案更新问题。

标签: java list arraylist


【解决方案1】:

试试这个对你有帮助。

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

【讨论】:

    【解决方案2】:

    您可以为groups 创建一个hashMap 结构,其中key 将为groupName,其值为出现次数。

    然后,只需将sorthashMap 结构按值descending 即可得到结果。

    【讨论】:

      【解决方案3】:

      这是我使用 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);
      

      【讨论】:

      • 谢谢,这看起来是最好的答案,但不幸的是我的应用程序适用于 java API 22,流需要 API 24 及更高版本。希望再用几年。
      【解决方案4】:

      这是流的一个很好的用例。这个想法是,首先将组的List&lt;TravelData&gt; 转换为Map&lt;String, Integer&gt; 到指南数(或指南到组数),然后按数字对该地图进行排序,只取地图的键(组/指南)并限制它是前三个元素。

      我假设 TravelData 有 String getGroup() 和 String getGuide() 方法:

      在示例中使用 Java 11 类型推断

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

      【讨论】:

        猜你喜欢
        • 2022-01-18
        • 2021-04-10
        • 1970-01-01
        • 2018-09-08
        • 2019-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多