在ArrayList中查找最常见的String

时间:2016-11-16 11:36:53

标签: java string list arraylist hashmap

我的问题有点不同。我有一个包含一些路由的ArrayList。例如:

[ACD, CDE, DEB, EBJ, BJK, JKO, ACD, CDE, DEX, EXB, XBJ, BJK, JKO, KOL]

当我使用HashMap进行计数时,它只会打印一个字符串:

Most common route: ACD
This route repeats 2 times.

这是正确的,但是,字符串CDE,BJK和JKO也重复了2次。由于我是编程的初学者,你会非常友善地告诉我在代码中需要更改什么,以便打印所有最常见的路径(字符串)。
这是代码:

Map<String, Integer> stringsCount = new HashMap<>();

    for(String string: listaRuta)
    {
      Integer count = stringsCount.get(string);
      if(count == null) count = new Integer(0);
      count++;
      stringsCount.put(string,count);
    }

    Map.Entry<String,Integer> mostRepeated = null;
    for(Map.Entry<String, Integer> e: stringsCount.entrySet())
    {
        if(mostRepeated == null || mostRepeated.getValue()<e.getValue())
            mostRepeated = e;
    }
    if(mostRepeated != null)
        System.out.println("Most common route: " + mostRepeated.getKey());
        System.out.println("This route repeats " + mostRepeated.getValue() + " times.");

4 个答案:

答案 0 :(得分:2)

以下是使用Eclipse Collections中的$(function(){ var longestLabel = $('label').outerWidth(); $('label').each(function(){ if ($(this).outerWidth() > longestLabel) { longestLabel = $(this).outerWidth(); } }); $('label').css('width', longestLabel); }); Bag的解决方案。

topOccurrences

输出:

MutableList<String> list =
        Lists.mutable.with("ACD", "CDE", "DEB", "EBJ", "BJK", "JKO", 
                "ACD", "CDE", "DEX", "EXB", "XBJ", "BJK", "JKO", "KOL");
MutableList<ObjectIntPair<String>> pairs =
        list.toBag().topOccurrences(1);
System.out.println(pairs);

[BJK:2, JKO:2, ACD:2, CDE:2] 类似于Bag,其中值是键的计数。在外部,Map<Key, Integer>的界面就像Bag。 Eclipse Collections具有原始集合,因此HashBag实现在内部使用Collection<Key>来提高效率。

ObjectIntHashMap上的方法topOccurrences具有处理关系的逻辑,这就是结果Bag中返回多个ObjectIntPair的原因。

注意:我是Eclipse Collections的提交者。

答案 1 :(得分:1)

package de.ninjaneers;

import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {

        String[] entries = {"ABC", "ABC", "DEF", "DEF", "DD", "MM"};
        Map<String, Long> counts = Arrays.stream(entries)
                .collect(Collectors.groupingBy(e -> e, Collectors.counting()));
        Long max = counts.entrySet().stream()
                .map(Map.Entry::getValue)
                .max(Long::compare)
                .orElse(0L);
        Map<String, Long> onlyTheMax = counts.entrySet().stream()
                .filter(e -> Objects.equals(max, e.getValue()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

    }
}

首先计算所有条目,然后计算最大值,最后筛选出小于最大值的所有条目。对不起,这是第一个简短的例子。

答案 2 :(得分:1)

另外,我更喜欢lamba解决方案来构建hasmap。获得地图后,这是您的目标的常用用途:

int maxValue=(Collections.max(stringsCount.values()));  // This will return max value in the Hashmap
for (Entry<String, Integer> entry : stringsCount.entrySet()) {  // Iterate through the hashmap
    if (entry.getValue()==maxValue) {
        System.out.println(entry.getKey());     // Print the key with max value
    }
}

或以更紧凑的方式使用java 8流和lamba:

long maxValue=(Collections.max(stringsCount.values()));
stringsCount.entrySet()
     .stream()
     .filter(s -> s.getValue() == maxValue).forEach(System.out::println);

答案 3 :(得分:0)

没有Streams和Lambdas的解决方案(初学者更容易理解):

测试类

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Counter {

    public static void main(String[] args) {
    List<String> test = new ArrayList<>();
    test.add("a");
    test.add("b");
    test.add("b");
    test.add("c");
    test.add("c");
    test.add("c");

    Map<String, Integer> stringsCount = new HashMap<>();

    for (String s : test) {
        if (stringsCount.get(s) == null) {
        stringsCount.put(s, 1);
        } else {
        stringsCount.replace(s, stringsCount.get(s) + 1);
        }
    }

        for (Map.Entry entry : stringsCount.entrySet()) {
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
    }
}

<强>输出

a,1 b,2 c,3