有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何检索根据其标记的帖子数量排序的收藏夹标记列表?

我不熟悉Java 8lambda表达式

我有一个List<Post>,其中每个Post可以属于多个post

class Post{
     String name;
     List<String> tags;
     ....
}

我想检索收藏夹标记列表,该列表根据它标记的帖子数量进行排序。如何使用lambda表达式实现它

存储在MongoDB中的JSON格式的示例输入:

[
    {
        "name": "java with spring",
        "tags": [
            "java",
            "spring"
        ]
    },
    {
        "name": "spring with mongodb",
        "tags": [
            "java",
            "spring",
            "mongodb"
        ]
    },
    {
        "name": "spring with hibernate",
        "tags": [
            "java",
            "spring",
            "hibernate"
        ]
    }
]

预期产出:

java,spring,mongodb,hibernate

以下是我在以下答案后尝试的内容:

List<Post> posts = ...

List<String> tags = new ArrayList<>();
Map<String, Integer> map = new TreeMap<String, Integer>();

// get list of all tags
posts.stream().forEach(post -> tags.addAll(post.getTags()));
// populate map with tag and its count (frequency)
tags.stream().forEach(tag -> map.put(tag, map.get(tag) == null ? 1 : map.get(tag) + 1));

Comparator<Entry<String, Integer>> byValue = (entry1, entry2) -> entry1.getValue().compareTo(entry2.getValue());
// sort the map by value and return the sorted keys as favorite tags
List<String> favoriteTags =  map.entrySet().stream().sorted(byValue.reversed()).map(e -> e.getKey()).collect(Collectors.toList())

共 (3) 个答案

  1. # 1 楼答案

    我不会使用lambda表达式,因为它们真的没有帮助

    否则我会使用Guava^{},然后按计数排序

    List<Post> posts = ... ;
    Multiset<String> tags = HashMultiset.create();
    posts.stream().forEach((p) -> tags.addAll(p.getTags()));
    // Now we have the frequency. Let's sort it.
    tags = Multisets.copyHighestCountFirst(tags);
    // You want only the tags and nothing else? No problem
    Set<String> strings = tags.elementSet();
    

    lambda不能解决所有问题。只需为正确的任务使用正确的工具

  2. # 2 楼答案

    您可以使用以下方法:

    static class Helper {
        String name;
        String tag;
    
        Helper(final String name, final String tag) {
            this.name = name;
            this.tag = tag;
        }
    
    }
    
    static void getFavourites() {
        final List<String> favourites =
                new ArrayList<Post>().stream().<Helper> flatMap(p -> p.tags.stream().map(t -> new Helper(p.name, t)))
                        .collect(groupingBy(h -> h.tag, Collectors.summingInt(x -> 1))).entrySet().stream()
                        .sorted(Comparator.comparingInt(e -> e.getValue()))
                        .map(e -> e.getKey())
                        .collect(toList());
    }
    

    (演员阵容出现只是因为Eclipse抱怨)。 其想法是反转帖子和标签之间的映射(也可以使用multimap实现),计算标签的出现次数并对它们进行排序

    当然,您必须用实际数据替换new ArrayList<Post>()

  3. # 3 楼答案

    我不知道是否可以在一个表达式中实现这一点,但可以通过两个步骤来实现,首先构建一个统计每个标记出现次数的映射:

    Map<String, Integer> tags = new HashMap<>();
    posts.forEach(p -> p.tags.forEach(t -> tags.put(t, tags.get(t) != null ? tags.get(t)+1 : 1)));
    List<String> sortedTags = tags.entrySet().stream().sorted((e1, e2) -> e2.getValue() - e1.getValue()).map(e -> e.getKey()).collect(Collectors.toList());