Java-当我得到一个值并进行更改时,集合是否总是更改

Java-当我得到一个值并进行更改时,集合是否总是更改,java,Java,我现在正在用Java编写一个程序,有点像服务器。我得到了一个MemberController,在MemberController中,它从数据库或缓存中获取Members(以加快进程)。这是它的外观示例: public class MemberController { private final TMap<Integer, Member> members; public MemberController() { this.members = new

我现在正在用Java编写一个程序,有点像服务器。我得到了一个
MemberController
,在
MemberController
中,它从数据库或缓存中获取
Members
(以加快进程)。这是它的外观示例:

public class MemberController {

    private final TMap<Integer, Member> members;

    public MemberController() {
        this.members = new THashMap<>();
    }

    public Member getMemberByID(int id) {
        if (members.containsKey(id)) {
            return members.get(id);
        }

        // GET DATA FROM DB
        members.put(ID, MEMBER);
        return MEMBER;
    }
System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());
BadgeController

public class Member {
    // FIELDS OF MEMBER HERE
    private BadgeController badgeController;

    public Member(ResultSet set) {
        // SET FIELDS
    }

    public void InitOtherData() {
        badgeController = new BadgeController(id);
    }

    public BadgeController getBadgeController() {
        return badgeController;
    }
public class BadgeController {

    private final int memberId;
    private final TMap<String, Badge> badges;

    public BadgeController(int memberId) {
        this.memberId = memberId;
        this.badges = new THashMap<>();

        // LOAD FROM DB
    }

    public Badge getBadge(String code) {
        return badges.get(code);
    }
System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());

我希望我的解释足够好。我很难解释。对不起。

Member=members.get(1)不复制对象,只是创建一个快捷方式(引用)。更改
成员
也会影响集合中的项目

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());

要创建有效副本,您必须使对象从
Cloneable
接口继承,并在其上调用
clone()
方法以获取副本。

Member=members.get(1)不复制对象,只是创建一个快捷方式(引用)。更改
成员
也会影响集合中的项目

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());

要创建有效的副本,您必须使对象从
Cloneable
接口继承,并在其上调用
clone()
方法以获取副本。

您需要通过以下方式深入复制对象:

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());
  • 实现克隆接口
  • 创建副本构造函数(最简单的解决方案为克隆)
示例:

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());
    // simple copy constructor 
    public SomerController(SomeController original) {
         members = orginal.clone();
    }


    // more advanced  copy constructor 
    public SomeController(SomeController original) {
        Set<Map.Entry<String, String>> entries = orginal.members.entrySet();
        members = new HashMap<String,Class>();
        Iterator<Map.Entry<String, Class>> iterator = entries.iterator();
        while(iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            String key = next.getKey();
            // if class contains a collections ( maps, arrays ) 
            // you need to provide a copy here 
            // ensure to copy whole tree of references 
            Class value next.getValue();
            map.put(key,value);
        }
    } 
//简单复制构造函数
公共SomerController(SomerController原件){
members=original.clone();
}
//更高级的复制构造函数
公共SomeController(SomeController原件){
Set entries=original.members.entrySet();
members=newhashmap();
迭代器迭代器=entries.Iterator();
while(iterator.hasNext()){
Map.Entry next=iterator.next();
String key=next.getKey();
//如果类包含集合(映射、数组)
//你需要在这里提供一份副本
//确保复制整个引用树
类值next.getValue();
map.put(键、值);
}
} 

您需要通过以下方式复制对象:

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());
  • 实现克隆接口
  • 创建副本构造函数(最简单的解决方案为克隆)
示例:

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive());
    // simple copy constructor 
    public SomerController(SomeController original) {
         members = orginal.clone();
    }


    // more advanced  copy constructor 
    public SomeController(SomeController original) {
        Set<Map.Entry<String, String>> entries = orginal.members.entrySet();
        members = new HashMap<String,Class>();
        Iterator<Map.Entry<String, Class>> iterator = entries.iterator();
        while(iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            String key = next.getKey();
            // if class contains a collections ( maps, arrays ) 
            // you need to provide a copy here 
            // ensure to copy whole tree of references 
            Class value next.getValue();
            map.put(key,value);
        }
    } 
//简单复制构造函数
公共SomerController(SomerController原件){
members=original.clone();
}
//更高级的复制构造函数
公共SomeController(SomeController原件){
Set entries=original.members.entrySet();
members=newhashmap();
迭代器迭代器=entries.Iterator();
while(iterator.hasNext()){
Map.Entry next=iterator.next();
String key=next.getKey();
//如果类包含集合(映射、数组)
//你需要在这里提供一份副本
//确保复制整个引用树
类值next.getValue();
map.put(键、值);
}
} 

为什么不测试一下呢?这就是说,您可能正在进行预优化,并打开了一大罐蠕虫:您现在必须处理缓存中过时的数据,并发访问非线程安全的可变数据结构,等等。只需使用数据库,它很快。我想知道它是否始终有效。解释起来很复杂,测试起来也很复杂。它比这更深入。是的,它总是有效的。任何数据结构都不会复制对象。它们只存储引用。当您不使用数据库、不保存更改时,也会出现问题,即设置加载到内存中的成员的某些属性的效果在程序结束时会丢失。而且数据库也有自己的缓存。@Bohemian是的,但当服务器停止/某个成员断开连接时,它会将更改保存到数据库中。有些东西会立即推送到数据库。这不是问题,你为什么不测试一下呢?这就是说,您可能正在进行预优化,并打开了一大罐蠕虫:您现在必须处理缓存中过时的数据,并发访问非线程安全的可变数据结构,等等。只需使用数据库,它很快。我想知道它是否始终有效。解释起来很复杂,测试起来也很复杂。它比这更深入。是的,它总是有效的。任何数据结构都不会复制对象。它们只存储引用。当您不使用数据库、不保存更改时,也会出现问题,即设置加载到内存中的成员的某些属性的效果在程序结束时会丢失。而且数据库也有自己的缓存。@Bohemian是的,但当服务器停止/某个成员断开连接时,它会将更改保存到数据库中。有些东西会立即推送到数据库。这不是问题,不管我走多深?例如,我做了一个引用,然后我设置了
BadgeController
,然后我更改了
badges
集中的一些内容,这些更改都是在原始
成员
集中进行的?@jean françois fabre我认为最好使用一个复制构造函数:)@ceph3us:你说得对。我想说的是,
clone()
很难掌握,因为当前克隆对象中包含的对象/引用树很深。不管我有多深?例如,我做了一个引用,然后我设置了
BadgeController
,然后我更改了
badges
集中的一些内容,这些更改都是在原始
成员
集中进行的?@jean françois fabre我认为最好使用一个复制构造函数:)@ceph3us:你说得对。我正要提到,
clone()
很难掌握,因为当前克隆对象中包含的对象/引用树很深。