我相信对我来说,逐步写出我必须做的事情并复制到目前为止的代码,而不是试图在较长的文本中进行解释,是比较容易的。

这是我要做的:


逐行读取文件
在这些行中映射键
通过1个键(以下代码中的getUri)和(获取另一个键的平均值(getRequestDuration))合并行
按合并的getRequestDuration的平均值排序(从高到低)
返回n的最高金额。


这就是我现在得到的:

try(Stream<String> logs = Files.lines(Paths.get(args))) {
  logs.map(LogLine::parseLine).limit(10).sorted((e1, e2) -> Integer.compare(e1.getRequestDuration(),
      e2.getRequestDuration()))
      .collect(Collectors.groupingBy(
      LogLine::getUri,
      Collectors.averagingDouble(LogLine::getRequestDuration)));
  return logs;


我是Java的新手,所以我有两个问题,希望有人可以为我回答:


收集/分组后如何排序?
如何适当限制?这样就限制了我返回的条目数量,而不是我经过的条目数量。


我(认为我)了解流的工作原理,但是在将其用于现实世界时遇到了麻烦。
我不一定要为我所遇到的问题寻找完整的代码,而不是可以为我提供了解如何做的信息的人。如果有人写出如何以正确的方式解决流问题的方法,我将不胜感激。

最佳答案

您可以在下面尝试,根据结果图按值对URI和平均持续时间进行分组,按值排序,并限制期望的结果数。

    Map<String, Double> uriDurationMap = logs.map(LogLine::parseLine).collect(Collectors.groupingBy(LogLine::getUri,Collectors.averagingDouble(LogLine::getRequestDuration)));


从地图排序和过滤

    Map<String, Double> filteredMap = uriDurationMap.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).limit(10).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));


要保留订单,请使用LinkedHashMap

    Map<String, Double> filteredMap = uriDurationMap.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).limit(10).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k,v) -> v, LinkedHashMap::new));


如果仅需要值,

    List<Double> filteredList = uriDurationMap.values().stream().sorted().limit(10).collect(Collectors.toList());

10-08 18:38