考虑以下案例
1)我需要保存Location类的对象(在我的应用程序中定义) 所有用户(在我的应用中定义)对象作为集合,如下所示
HashMap<Location, Collection<Person>>
并且数据在HashMap中存储如下(作为对象,我提到名称进行解释)
Location1 - User1, User2, User3
Location2 - User2, User3
Location3 - User1
现在在上面的例子中,在hashmap中,User1,User2和User3的冗余副本存储在每个Location中。这是保存集合中一对多关系数据的正确方法吗?
答案 0 :(得分:4)
没有“冗余”。所有hashmap存储都是对同一对象的引用。
答案 1 :(得分:2)
Person1中包含的信息只存储一次,除非您做了明确制作该对象副本的内容(例如,通过使用clone()方法,如果已实现)
通常,将person1之类的对象添加到多个集合中不应该使整个新对象与第一个对象相同并将其放入集合中。发生的事情是,对象被保存在不同的集合中有多个引用。与整个新对象的大小相比,每个引用都很小,虽然您可能有多个对同一对象的引用,但该Person对象管理的信息(如名称,电子邮件等)只存储一次。
因此:您对集合的处理很好,它不会创建对象的多个副本。
(java中没有指针,但是如果你曾经研究过一种允许它们的语言,那么这个想法很相似,因为多个较小的指针可以指向一个大的对象)
答案 2 :(得分:2)
Person
是对象的引用。当您将它传递给add()
或put()
这样的方法时,您会给它一个引用的副本(即使在64位JVM上也通常是32位)
这意味着您的收藏集可以包含相同引用的“冗余”副本,但如果您希望在多个地方引用该引用,我看不到解决方法。
答案 3 :(得分:0)
不需要HashMap
。User
课程中可以包含Location
,因为它完全符合您的要求。
public class Location {
private Set<User> users = new HashSet<User>();
public boolean addUser(User user) {
return users.add(user);
}
public boolean remove(User user) {
return users.remove(user);
}
public Set<User> getAll() {
return Collections.unmodifiableSet(users);
}
}
答案 4 :(得分:0)
public class Location {
private Set<User> users = new HashSet<User>();
public boolean addUser(User user) {
return users.add(user);
}
public boolean remove(User user) {
return users.remove(user);
}
public Set<User> getAll() {
return Collections.unmodifiableSet(users);
}
}
与Amit的答案相同,只需保留与Set<User>
相关联的Location
即可。然后,您还应该使用ArrayList<Location>
来存储您的所有Locations
。正如Arjun所指出的那样,没有冗余(重复的用户对象)。什么时候没有冗余?每个User
对象仅创建一次,然后添加到多个集合中。这是因为User
的引用实际上存储在Collection中。这就是Java中“通过值传递引用”的含义。例如,在List的add方法中,您可以调用add(User)
,但Java在后台执行的操作是将User
对象的引用(思考内存位置)的副本传递给List。因此List实际上并不直接存储用户对象,但它位于某个内存中。