使用流从列表中获取前3个计数

-2 java java-8 java-stream

我正在尝试将java7程序转换为java8。我想在下面使用流API进行输出。

public List<String> getTopThreeWeatherCondition7() {
    List<String> _Top3WeatherList = new ArrayList<String>();
    Map<String, Integer> _WeatherCondMap = getWeatherCondition7();
    List<Integer> _WeatherCondList = new ArrayList<Integer>(_WeatherCondMap.values());
    Collections.sort(_WeatherCondList, Collections.reverseOrder());
    List<Integer> _TopThreeWeathersList = _WeatherCondList.subList(0, 3);
    Set<String> _WeatherCondSet = _WeatherCondMap.keySet();
    Integer count = 0;
    for (String _WeatherCond : _WeatherCondSet) {
        count = _WeatherCondMap.get(_WeatherCond);
        for (Integer _TopThreeWeather : _TopThreeWeathersList) {
            if (_TopThreeWeather == count) {
                _Top3WeatherList.add(_WeatherCond);
            }
        }
    }
    _WeatherCondList = null;
    _WeatherCondMap = null;
    _TopThreeWeathersList = null;
    _WeatherCondSet = null;
    return _Top3WeatherList;

}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 5

我强烈建议遵守Java编码约定。以小写字母而不是_+大写字母开头的变量名称。其次,不要null在使用后分配局部变量。这是过时的,并偏离了代码的实际目的。另外,请勿使用未使用的默认值来初始化变量(例如count = 0)。在这种特定情况下,您还应该在实际使用它的内部循环内声明该变量。

另请注意,您正在比较Integer参考而不是值。在这种特定情况下,它可能会工作,因为对象源自同一地图,但是您应该避免这种情况。目前尚不清楚是否可能存在重复值;在这种情况下,此循环将无法正确执行操作。另外,您不应迭代keySet(),而只是get对每个键进行查找,因为这样entrySet()可以一起迭代键和值。

如您所言,该代码应该是“ Java 7程序”,您应该注意“钻石运算符”(<>)的存在,从而消除了在创建泛型类的新实例时重复输入类型参数的需求。

您应该首先对条目进行排序,而不是仅对值进行排序并搜索关联的键。

因此,原始代码的干净的Java 7变体将是:

static final Comparator<Map.Entry<String, Integer>> BY_VALUE_REVERSED=
    new Comparator<Map.Entry<String, Integer>>() {
        public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            return Integer.compare(o2.getValue(), o1.getValue());
        }
    };
public List<String> getTopThreeWeatherCondition7() {
    List<String> top3WeatherList = new ArrayList<>();
    Map<String, Integer> weatherCondMap = getWeatherCondition7();
    List<Map.Entry<String, Integer>> entryList=new ArrayList<>(weatherCondMap.entrySet());
    Collections.sort(entryList, BY_VALUE_REVERSED);
    List<Map.Entry<String, Integer>> topThreeEntries = entryList.subList(0, 3);
    for(Map.Entry<String, Integer> entry: topThreeEntries) {
        top3WeatherList.add(entry.getKey());
    }
    return top3WeatherList;
}
Run Code Online (Sandbox Code Playgroud)

这也可以正确处理重复项。只有在并列第三的情况下,才会选择一个有效的候选人。


除非您有一个干净的起点,否则您可能会看到,这可以从Java 8功能中受益

  • List您可以Stream从创建权限,Map并告诉流进行排序,而不是将内容复制到进行排序
  • 您可以更轻松地创建比较器,甚至可以使用新的内置比较器之一
  • 您可以将将结果限制为三个元素的任务链接起来,映射到键,并List直接在前面的步骤的流中收集到结果:
public List<String> getTopThreeWeatherCondition7() {
    Map<String, Integer> weatherCondMap = getWeatherCondition7();
    List<String> top3WeatherList = 
        weatherCondMap.entrySet().stream()
            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
            .limit(3)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
    return top3WeatherList;
}
Run Code Online (Sandbox Code Playgroud)