use*_*969 5 java sorting java-8 java-stream
输入 :
List<String> elements= new ArrayList<>();
elements.add("Oranges");
elements.add("Figs");
elements.add("Mangoes");
elements.add("Apple");
List<String> listofComments = new ArrayList<>();
listofComments.add("Apples are better than Oranges");
listofComments.add("I love Mangoes and Oranges");
listofComments.add("I don't know like Figs. Mangoes are my favorites");
listofComments.add("I love Mangoes and Apples");
Run Code Online (Sandbox Code Playgroud)
输出:[芒果、苹果、橙子、无花果] -> 输出必须按元素出现次数的降序排列。如果元素出现等于 no。那么它们必须按字母顺序排列。
我是 Java 8 的新手,遇到了这个问题。我尝试部分解决它;我无法排序。谁能帮助我编写更好的代码?
我的一段代码:
Function<String, Map<String, Long>> function = f -> {
Long count = listofComments.stream()
.filter(e -> e.toLowerCase().contains(f.toLowerCase())).count();
Map<String, Long> map = new HashMap<>(); //creates map for every element. Is it right?
map.put(f, count);
return map;
};
elements.stream().sorted().map(function).forEach(e-> System.out.print(e));
Run Code Online (Sandbox Code Playgroud)
输出:{苹果=2}{无花果=1}{芒果=3}{橙子=2}
在现实生活中,您必须考虑到,当数量增长时,将任意数量的匹配操作应用于任意数量的评论可能会变得非常昂贵,因此\xe2\x80\x99s值得做一些准备:
\n\nMap<String,Predicate<String>> filters = elements.stream()\n .sorted(String.CASE_INSENSITIVE_ORDER)\n .map(s -> Pattern.compile(s, Pattern.LITERAL|Pattern.CASE_INSENSITIVE))\n .collect(Collectors.toMap(Pattern::pattern, Pattern::asPredicate,\n (a,b) -> { throw new AssertionError("duplicates"); }, LinkedHashMap::new));\nRun Code Online (Sandbox Code Playgroud)\n\nPredicate即使不进行正则表达式匹配,该类也非常有价值。LITERAL和标志的组合CASE_INSENSITIVE可以使用预期语义进行搜索,而无需将整个字符串转换为小写(顺便说一句,这不足以满足所有可能的情况)。对于这种匹配,准备工作将包括为Boyer\xe2\x80\x93Moore 算法构建必要的数据结构,以便在内部进行更有效的搜索。
这张地图可以重复使用。
\n\n对于您的特定任务,使用它的一种方法是
\n\nfilters.entrySet().stream()\n .map(e -> Map.entry(e.getKey(), listofComments.stream().filter(e.getValue()).count()))\n .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))\n .forEachOrdered(e -> System.out.printf("%-7s%3d%n", e.getKey(), e.getValue()));\nRun Code Online (Sandbox Code Playgroud)\n\n这将打印您的示例数据:
\n\nMangoes 3\nApple 2\nOranges 2\nFigs 1\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,filters映射已经按字母顺序排序,并且对于具有定义的遇到顺序的流来说,sorted第二个流操作是稳定的,因此只需按出现次数排序,具有相等元素的条目将保持其相对顺序,即字母顺序从源地图。
Map.entry(\xe2\x80\xa6)需要 Java\xc2\xa09 或更高版本。对于 Java\xc2\xa08,\xe2\x80\x99d 必须使用类似
\n的内容new AbstractMap.SimpleEntry(\xe2\x80\xa6)。