========================
List是Collection的子类,也是一个接口,所以方法也差不多的
ArrayList实现了Collection和List
所以ArrayList和List里的方法大部分都差不多
只有一个方法需要注意,下面的方法在ArrayList里没有,但是如果是list list1=new ArrayList()那么就可以使用接口的这2个方法
ArrayList是一个动态数组,不是线程安全的,特点是查询快,增删慢,一般是配合List接口使用
我们可以发现ArrayList并没有插入insert方法
ArrayList 底层是维护了一个Object数组实现的,使用无参构造函数时,Object数组默认的容量是10,当长度不够时,自动增长0.5倍,是原来的1.5倍,且只有使用add方法时才会判断容量并且自动增加
下面使用ArrayList的方法来综合使用
需求1
1 使用ArrayList创建list1,list2实例,2个都添加人物对象(人物名,id),然把list2的对象都加入到list1里,清除list2里的内容
2 使用constains来根据人物id判断是否存在id为1的,然后使用iterator遍历集合的所有元素,再用get来遍历集合的所有元素
3 查找id为2的Person对象,然后替换这个Person对象的name属性,
4 截取指定索引之间的一些元素,把这些元素转换到数组
class Test
{
public static void main(String[] args)
{
List<Person> list1 = new ArrayList<Person>();
list1.add(new Person("aa", 1)); // 添加元素
list1.add(new Person("bb", 2));
list1.add(new Person("cc", 3));
List<Person> list2 = new ArrayList<Person>();
list2.add(new Person("dd", 4));
list2.add(new Person("ee", 5));
list2.add(new Person("ff", 6));
list1.addAll(list2); // 把list2里的元素全都加入到list1的后面
list2.clear(); // 清空list2的元素
System.out.println(list1);
//需要重写Person的equals方法
System.out.println("是否已经存在该对象"+list1.contains(new Person("天帝", 1)));
//使用Iterator遍历元素
Iterator<Person> iterator=list1.iterator();
while (iterator.hasNext())
{
Person person = (Person) iterator.next();
System.out.println(person);
}
//使用get遍历元素
for (int i = 0; i < list1.size(); i++)
{
Person person = list1.get(i);
System.out.println(person);
}
//查找id为2的Person对象的索引
int index=list1.indexOf(new Person("xxx", 2));
//替换id为2的Person对象的name属性
list1.set(index,new Person("帝屠", 2));
System.out.println(list1);
//接取指定索引之间的一些元素,截取3个
List<Person>list3=list1.subList(0,3);
Object []object=list3.toArray();
for (Object object2 : object)
{
System.out.println(((Person)object2));
}
}
}
class Person
{
public Person(String name, int id)
{
this.name = name;
this.id = id;
}
public String name;
public int id;
@Override
public String toString()
{
return "Person [name=" + name + ", id=" + id + "]";
}
@Override
public boolean equals(Object obj)
{
Person temp = (Person) obj;
if (this.id == temp.id)
{
return true;
}
return false;
}
}
需求2 使用listIterator遍历元素
listIterator的方法,比普通的Iterator功能强大
add是插入到集合的前面位置
previous可以逆向遍历,是先指向上一个指针再读取那个指针出的数值,所以一开始必须要用next()来移动一下指针到第一个元素的位置
而next则相反,是读取下一个元素的,而且是先读取那个元素,再移指针,previous是先移指针再读元素
注意:
迭代器在迭代元素的过程中,不允许使用集合对象改变集合中的元素个数,如果需要添加或者删除
只能使用迭代器的方法进行操作,这个后面会有说明为什么
public class Test2
{
public static void main(String[] args)
{
List list1 = new ArrayList();
list1.add("1");
list1.add("2");
list1.add("3");
list1.add('4');
System.out.println(list1);
ListIterator iterator1 = list1.listIterator();
//previous是先把指针移到前面去,然后读取数值,所以不能直接使用,因为前面没有元素
//System.out.println(iterator1.previous());
//向集合的头部添加数据
iterator1.add("5");
System.out.println(list1);
//但是添加了一个元素在同步后,iterator指针的前面就有元素了,便可读取
System.out.println(iterator1.previous());
System.out.println("========");
//遍历集合,可以逆向遍历
while (iterator1.hasNext())
{
Object object = (Object) iterator1.next();
System.out.println(object);
//iterator1.add("666"); //不能在迭代的时候向集合加入数值,
// 首先我们要明确,我们上面的6666是用iterator加入的,而不是list加入的,
// 而add是插入到 next 返回的下一个元素的前面,并且add方法的内部,会把指针的位置+1,也就相当于内存地址+4,
// 如果一开始就add,此时next返回的下一个元素是第一个元素,就是说一开始的时候是插到最前面,
// 所以是[6666, 1, 2, 3, 4],然后会把指针的位置+1,这样指针就到了 1的位置,而非6666处
// 这样遍历的时候是从1开始遍历的,所以遍历不到6666
// 但是确实插入进去了,在循环外输出即可
//
}
}
}