如何正确订购地图?

时间:2018-05-18 20:37:35

标签: java list comparator

所以我试图订购一个Map,我了解到java中有一个名为Comparator的东西可以帮助我做到这一点,但出于某种原因它似乎有没有错误,但程序没有工作......它似乎有一个无限的cicle但我不知道在哪里。

public long[] top_most_active (TCD_community com, int N){
    int i=0;
    long[] array= new long[N];
    Arrays.fill (array,0);

    List<User> l = new ArrayList<>();
    l = topX (N, com);

    for (User u : l) {
        array[i] = u.getid();
        System.out.println (u.getid());
        i++;
    }
    return array;
}

我想订购所有内容并在我的列表中找到top N users的帖子最多!

public List<User> topX(int x , TCD_community com) {
    List<User> l = new ArrayList<>();
    Map<Integer, User> m = com.getUsers(); 
    for (Map.Entry<Integer, User> entrada : m.entrySet()) {
        User u = entrada.getValue();
        l.add(u);
        l.sort(new Comparator<User>() {
            public int compare(User u1, User u2) {
                if(u1.getpost_count() == u2.getpost_count()){
                    return 0;
                }
                else if (u1.getpost_count() > u2.getpost_count())
                    return -1;
                else return 1;
            }
        });
    }
    return l.subList(0,x);
}

3 个答案:

答案 0 :(得分:3)

你过于复杂的事情。请考虑以下事项:

top_most_active方法变为:

public long[] top_most_active (TCD_community com, int N){
       long[] result = topX(N, com).stream()
                                   .mapToLong(User::getId)
                                   .peek(id -> System.out.println(id))
                                   .toArray();
}

然后topX方法变为:

public List<User> topX(int x , TCD_community com) {
    return com.getUsers() 
              .stream()
              .map(e -> e.getValue())
              .sorted(Comparator.comparingLong(User::getpost_count).reversed())
              .limit(x)
              .collect(Collectors.toCollection(ArrayList::new));
}

这解决了您尝试在循环的每次迭代中对累积列表进行排序以及删除当前具有的大部分冗余和样板代码的问题。

答案 1 :(得分:1)

您正在尝试在将每个条目添加到列表后对列表进行排序。

您应该只是将所有用户收集到一个新列表中,然后对列表进行排序。

List<User> l = new ArrayList<>(com.getUsers().values());
l.sort( ... your comparator ...);
return l.subList(0, x);

答案 2 :(得分:1)

好的,所以您似乎不想订购地图,您想订购一个清单。

我认为你的代码现在做的事情很多:(1)它出于某种原因处理Map。我想这就像Python enumerate(your_list)给出你的索引,但这是不必要的。 (2)它似乎也在每次添加时对列表进行重新排序。你不需要这样做。

只需获取所有元素,然后一次性对其进行排序。获取东西是一项相对简单的任务。比较和订购它们相对昂贵,因此您希望尽量减少必须这样做的时间。

但是,为了排序您的列表,只需实现Comparator并使用它调用排序方法。现在这样做非常简单,因为我们在int(以及IntegerlongLong等方面都有自然顺序,并且可以通过{{1}轻松创建比较器}。

获取用户列表。然后,

Comparator#comparing

假设您的Map<Integer, User> map = magicSupplier(); List<User> users = new ArrayList<>(map.values()); Comparator<User> comparator = Comparator.comparing(User::postCount) Collections.sort(users, comparator.reversed()); // for most-to-least 对象有一个方法User返回一个自然排序的整数或postCount来计算帖子的数量。我认为你称之为不同的东西。

然后进行子列表并返回。