是否有在Java中实现NavigableSet的HashSet?

时间:2014-10-21 19:47:05

标签: java collections hashset

我需要解析一些网站以获取用户及其帖子的列表。 用户由UserIds表示,PostIds表示,实际上是整数。 所以我为这样的用户创建了一个类:

class User {
    private int userId;
    private List<Integer> postList;
    //...
}

然后我遇到了问题。 该站点提供了一个api,它返回一个帖子结构列表,如:

class Post {
    int postId;
    int postAuthorId;
    String postText;
    //...
}

所以我应该找一个帖子,搜索我的用户集中是否已经有帖子作者(用户),如果没有,添加新用户并将id发布到用户集,如果是 - 将帖子ID添加到该用户列表中帖子。 首先,我想使用HashSet - 因为快速添加和搜索方法。但后来我意识到我无法从HashSet获得所需的用户。接下来我考虑了实现TreeSet的{​​{1}},因此我可以使用NavigableSet。它返回对象,所以我可以修改它。一切都很好,但TreeSet.ceiling(user)HashSet快得多。 所以问题是,如果有某种TreeSet可以返回特定对象,就好像它正在实现HashSet一样? 或者我应该以某种方式重写我的代码?将不胜感激。

4 个答案:

答案 0 :(得分:3)

HashSet更快的原因是因为它没有排序。需要对NavigableSet进行排序,并且任何实现都必须在保持有序集合方面有一些开销。 TreeSet可能是最好的通用排序集实现,如果您需要NavigableSet带来的功能,则需要支付性能费用。我非常怀疑设置查找中的开销在任何情况下都是程序的关键点。

答案 1 :(得分:1)

来自NavigableSet Javadoc,

所有已知的实施类:    ConcurrentSkipListSetTreeSet

由于散列函数会破坏任何类型的自然顺序,我认为基本散列不可能NavigableSet

答案 2 :(得分:1)

作为我评论的扩展,这听起来像是HashMap的实际用途。您可以使用User中的用户ID作为键,并映射到User对象。使用您提供给我们的内容,下面的代码将填充用户HashMap。

HashMap<Integer, User> users = new HashMap<>();

for(Post post : posts) {
    int userId = post.getPostAuthorId();
    if(users.get(userId) != null) {
        users.get(userId).addPost(post);
    }
    else {
        users.put(userId, new User(userId));
    }
}

答案 3 :(得分:0)

您应该将用户列表和帖子列表分开。然后使用适合您目的的地图来关联它们。如果你使用hibernate这样的东西,你就可以继续使用它们作为POJO并从中获得持久性。

如果你想将帖子保留在用户中,你可能还会重写你的User类的哈希函数,这样该类将仅由userID而不是帖子ID。 (以及重写equals

此处有更多内容Why is the default hashcode() in java bad?