Java ArrayList修改由";返回的值;获得;方法
我有以下两种情况与ArrayListJava ArrayList修改由";返回的值;获得;方法,java,android,arraylist,Java,Android,Arraylist,我有以下两种情况与ArrayListget方法相关,一种是自定义类,另一种是字符串类: 1。下面是修改自定义类ArrayList元素的示例: ArrayList<MyClass> mTmpArray1 = new ArrayList<MyClass>(); MyClass myObj1 = new MyClass(10); mTmpArray1.add(myObj1); MyClass myObj2 = mTmpArray1.get(0); myObj2.myI
get
方法相关,一种是自定义类,另一种是字符串类:
1。下面是修改自定义类ArrayList元素的示例:
ArrayList<MyClass> mTmpArray1 = new ArrayList<MyClass>();
MyClass myObj1 = new MyClass(10);
mTmpArray1.add(myObj1);
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
MyClass myObj3 = mTmpArray1.get(0);
Log.d(TAG, "Int Value:"+myObj3.myInt); // Prints "20"
ArrayList<String> mTmpArray2 = new ArrayList<String>();
mTmpArray2.add("Test_10");
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
String myStr2 = mTmpArray2.get(0);
Log.d(TAG, "Str Value:"+myStr2); // Prints "Test_10"
ArrayList mTmpArray1=新的ArrayList();
MyClass myObj1=新的MyClass(10);
mTmpArray1.add(myObj1);
MyClass myObj2=mTmpArray1.get(0);
myObj2.myInt=20;
MyClass myObj3=mTmpArray1.get(0);
Log.d(标记,“Int值:”+myObj3.myInt);//打印“20”
2。下面是修改字符串ArrayList元素的示例:
ArrayList<MyClass> mTmpArray1 = new ArrayList<MyClass>();
MyClass myObj1 = new MyClass(10);
mTmpArray1.add(myObj1);
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
MyClass myObj3 = mTmpArray1.get(0);
Log.d(TAG, "Int Value:"+myObj3.myInt); // Prints "20"
ArrayList<String> mTmpArray2 = new ArrayList<String>();
mTmpArray2.add("Test_10");
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
String myStr2 = mTmpArray2.get(0);
Log.d(TAG, "Str Value:"+myStr2); // Prints "Test_10"
ArrayList mTmpArray2=新的ArrayList();
mTmpArray2.添加(“试验10”);
字符串myStr1=mTmpArray2.get(0);
myStr1=“测试20”;
字符串myStr2=mTmpArray2.get(0);
Log.d(标签,“Str值:”+myStr2);//打印“测试10”
因此,在MyClass ArrayList的情况下,当我调用get
并修改值时,当我再次执行get
时,我看到更改正在反映出来
但当我修改字符串ArrayList时,同样的方式,那个么更改并没有反映出来
两种情况下的get
方法有什么不同?对于String,String类创建深度复制并返回新对象,对于自定义类创建浅层复制吗
在适用于“LinkedHashMap”的第一个场景中,“HashMap”和“List”?字符串是不可变的。您没有将新字符串插入数组列表 当您执行
String myStr2=mTmpArray2.get(0)时代码>,即使您指向ArrayList中的引用,任何更改该值的尝试都将(由于字符串不变性)创建一个不再引用ArrayList的新字符串(myStr2)
当您执行myStr1=“xxx”
操作时,实际上并不是在更改ArrayList引用,而是在更改从ArrayList抓取的一个新(副本)(现在称为myStr1),它具有本地作用域
阅读有关字符串的更多信息:
现在在第一个示例中,您指向一个可变对象(您的自定义类),因此您实际上通过引用更改了直接值。欢迎来到Java
不相关的:此代码:MyClass myObj1=新的MyClass(10)代码>被(可以说)认为是坏的。最好使用更易于阅读的工厂模式。换句话说,带有参数的公共构造函数很难阅读(例如,当我阅读您的代码时,我不知道我在构造什么)
(也许)更好的方法是:MyClass myObj=MyClass.createInstanceWithCapacity(10);//我发明这个名字是因为我不知道你的10是什么,但看看这两个,你认为哪一个乍一看更容易理解?
免责声明:上述无关评论是我个人的意见,并非所有开发者都会同意。;) 您的客户在这两种情况下做的事情不同
在此更新对象的状态,因此更改会影响列表中存储的对象:
myObj2.myInt = 20;
myStr1.setSomething(...);
在这里,您将为局部变量指定一个新对象,因此列表不受影响:
myStr1 = "Test_20";
myObj2 = new MyClass (...);
如果String
是可变的,您可以通过调用某个方法来修改字符串,并且更改会反映在列表中存储的对象中:
myObj2.myInt = 20;
myStr1.setSomething(...);
另一方面,如果在第一种情况下更改了局部变量的值,则存储在列表中的对象不会受到影响:
myStr1 = "Test_20";
myObj2 = new MyClass (...);
这两个“get”调用之间没有区别。区别在于ArrayList所持有的类型和“get”方法返回的引用之间的区别
在第一个示例中,您可以执行以下操作:
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
在这里,您将在位置0的ArrayList中获得对MyClass实例的引用,并且您正在修改此实例中的一个字段
在第二个示例中,您可以执行以下操作:
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
在这里,您将获得对数组列表中字符串实例的引用,然后您将向myStr1提供对您创建的另一个字符串的引用(“Test_20”)。就好像你写了myObj2=newmyclass(20)代码>在第一个示例的第二行中
简言之,在第一个示例中,您可以通过从抓取的引用更改对象内的字段来访问该字段。在第二个示例中,您只是将引用更改为指向不同的字符串
我还应该提到,在Java中,字符串是不可变的,这意味着一旦创建了字符串,就不能对其进行更改。String是一个不可变的类。线条
myStr1 = "Test_20";
不会更改myStr1
所指向的字符串对象的值。相反,将创建一个新字符串,并修改myStr1
以指向新字符串。原始字符串保持不变,可以从ArrayList中检索
您的MyClass
对象显然是可变的。仅创建一个实例,其状态由赋值更改
myObj2.myInt = 20;
因此,当从ArrayList中检索此对象时,将看到其新状态。在第二个示例中,您只需不更改列表即可
在第一个示例中,您正在执行以下操作:
从列表中获取第一个对象,并将其存储在名为“myObj2”的变量中
通过设置此对象的int值,修改存储在变量“myObj2”中的对象
但你的第二个例子完全不同:
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
让我来翻译一下:
从列表中获取第一个元素,并将其存储在名为“myStr1”的变量中
将变量“myStr1”的值设置为“Test\u 20”
因此,在第一种情况下,您正在修改列表中存储的对象的变量。在第二种情况下,您正在检索列表中存储的对象,然后重新使用存储该检索对象的变量并将其用于新的内容,但这当然不会改变原始列表
修改您的列表