List概述
List接口是一个继承了集合(Collection)接口的有序集合的接口,常见的ArrayList、LinkedList都以不用形式来实现List接口。具体说明参考源代码或Oracle文档。
add()方法
add()方法是将指定的元素附加到此列表的末尾。
* Appends the specified element to the end of this list (optional
* operation).
*
* <p>Lists that support this operation may place limitations on what
* elements may be added to this list. In particular, some
* lists will refuse to add null elements, and others will impose
* restrictions on the type of elements that may be added. List
* classes should clearly specify in their documentation any restrictions
* on what elements may be added.
在列表的末尾添加元素,但是在使用是,如果添加的是自定义的对象时,却不是直接添加该对象,而是添加该对象的引用(或者说地址);如果添加的是String、int等基本类型数据时,添加的是本身的值,而不是引用。以下测试印证。
测试
使用ArrayList测试,分别添加元素为基本类型和自定义对象。
基本类型
String类型
public void testStringList(){
String name = "";
List<String> list = new ArrayList<String>();
System.out.println("------------part 1------------");
System.out.println("-----name:"+name+",hashcode:"+name.hashCode());
System.out.println("-----list:"+list.toString()+",hashcode:"+list.hashCode());
name="aaa";
list.add(name);
System.out.println("------------part 2------------");
System.out.println("-----name:"+name+",hashcode:"+name.hashCode());
System.out.println("-----list:"+list.toString()+",hashcode:"+list.hashCode());
name="bbb";
list.add(name);
System.out.println("------------part 3------------");
System.out.println("-----name:"+name+",hashcode:"+name.hashCode());
System.out.println("-----list:"+list.toString()+",hashcode:"+list.hashCode());
}
打印的结果:
------------part 1------------
-----name:,hashcode:0
-----list:[],hashcode:1
------------part 2------------
-----name:aaa,hashcode:96321
-----list:[aaa],hashcode:96352
------------part 3------------
-----name:bbb,hashcode:97314
-----list:[aaa, bbb],hashcode:3084226
part 1 为初始阶段,没有赋值时name值为空,list也为空(此时list的hashcode为1,是另外一个问题了);part 2 和 part 3 的区别是重点,为name赋了不同的值,hashcode发生变化,list中的数据不同。此时list存储的是基本类型元素的值。
其他类型
Integer等基本类型测试也适用。
自定义类
自定义测试类:
public class BaseEntity {
private String id;
private String name;
public BaseEntity(String id){
this.id=id;
};
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "id:"+this.id+",name:"+this.name;
}
}
不同对象
测试代码:
public void testOtherObjectList(){
List<BaseEntity> list = new ArrayList<BaseEntity>();
BaseEntity entity_1 = new BaseEntity("a1");
entity_1.setName("name-3");
list.add(entity_1);
System.out.println("----------part 1-----------");
System.out.println("---entity-----hashcode:"+entity_1.hashCode()+"--------toString:"+entity_1.toString());
System.out.println("---list-------hashcode:"+list.hashCode()+"--------toString:"+list.toString());
System.out.println(list.get(0));
BaseEntity entity_2 = new BaseEntity("a2");
entity_2.setName("name-4");
list.add(entity_2);
System.out.println("----------part 2-----------");
System.out.println("---entity-----hashcode:"+entity_2.hashCode()+"--------toString:"+entity_2.toString());
System.out.println("---list-------hashcode:"+list.hashCode()+"--------toString:"+list.toString());
System.out.println(list.get(0));
System.out.println(list.get(1));
}
打印结果:
----------part 1-----------
---entity-----hashcode:1838148248--------toString:id:a1,name:name-3
---list-------hashcode:1838148279--------toString:[id:a1,name:name-3]
id:a1,name:name-3
----------part 2-----------
---entity-----hashcode:57858394--------toString:id:a2,name:name-4
---list-------hashcode:1205880195--------toString:[id:a1,name:name-3, id:a2,name:name-4]
id:a1,name:name-3
id:a2,name:name-4
part 1是添加第一个元素,part 2是添加第二个元素。两次添加的元素,类相同但却是两个实例对象。两个对象的hashcode不同,赋值不同,添加到list中,list的内容也不同。
同一个对象
测试代码:
public void testObjectList(){
List<BaseEntity> list = new ArrayList<BaseEntity>();
BaseEntity entity_1 = new BaseEntity("b1");
entity_1.setName("name-1");
list.add(entity_1);
System.out.println("----------part 1-----------");
System.out.println("---entity-----hashcode:"+entity_1.hashCode()+"--------toString:"+entity_1.toString());
System.out.println("---list-------hashcode:"+list.hashCode()+"--------toString:"+list.toString());
System.out.println(list.get(0));
entity_1.setId("b2");
entity_1.setName("name-2");
list.add(entity_1);
System.out.println("----------part 2-----------");
System.out.println("---entity-----hashcode:"+entity_1.hashCode()+"--------toString:"+entity_1.toString());
System.out.println("---list-------hashcode:"+list.hashCode()+"--------toString:"+list.toString());
System.out.println(list.get(0));
System.out.println(list.get(1));
}
打印结果:
----------part 1-----------
---entity-----hashcode:88633879--------toString:id:b1,name:name-1
---list-------hashcode:88633910--------toString:[id:b1,name:name-1]
id:b1,name:name-1
----------part 2-----------
---entity-----hashcode:88633879--------toString:id:b2,name:name-2
---list-------hashcode:-1458682207--------toString:[id:b2,name:name-2, id:b2,name:name-2]
id:b2,name:name-2
id:b2,name:name-2
part 1是添加第一个元素,part 2是添加第二个元素。两次添加过程中,同一个对象两次赋值,属性值变了但是hashcode值没有变,过程中对象的存储没有改变;但是list在第二次执行add()方法后,两个位置中的元素值相同。此时list中的第一个元素值改变了,对比不同对象添加的结果,可以说明list存储的是该元素对象的引用。
结论
List在执行add()方法时,如果添加的元素是基本类型,则添加的是基本类型的值,而如果添加的是自定义的类对象时,添加的实际上是该对象的引用或者说是虚拟地址,在需要list中的某个元素时,还是根据这个引用查找该对象。