集合
-
集合和数组的区别:
-
相同点:都可以存储多个数组
-
不同点:
-
数组中可以存多个数据,但是不能自由的实现数据的新增和删除操作
集合中除了可以存储多个数据,还可以自由的实现数据的新增和删除操作
-
数组中及可以存储基本类型的数据有可以存储引用类型数据
集合中只能存储引用类型数据
-
数组本身自带的功能较少,集合中自带的功能比较多
-
-
集合的体系
Collection集合
- 特点
- 是一个接口不能去创建对象。只能通过实现类创建对象访问其中的方法。
- 在java.util包,需要导包使用
- Collection中定义的方法,子接口和实现类都可以去使用。
Collection集合中常用的方法
- **add(E e) :**往集合中添加元素
- **addAll(Collection<? extends E> c) :**将集合c中的内容全添加到调用者集合中
- **remove(Object o) :**删除集合中的o元素
- **removeAll(Collection<?> c) :**删除调用者集合中和c集合中相同的元素
- **clear() :**清空集合
- **contains(Object o) :**判断集合中是否包含元素o
- **containsAll(Collection<?> c) :**判断调用者集合中是否全部包含集合c的所有元素
- **isEmpty() :**判断集合是否为空
- **size() :**返回集合中元素的个数
//创建Collection的实现类list,用接口接收
Collection c = new ArrayList();
//添加add
c.add("chen");
c.add("shuang");
System.out.println(c);
Collection c1 = new ArrayList();
c1.add("1999");
c1.add("0328");
c1.add(4);
//add All
c.addAll(c1);
System.out.println(c);
//删除集合中的元素
c.remove("chen");
//删除集合c中和集合c1中相同的元素
c.removeAll(c1);
System.out.println(c);
//判断集合中包含某一个元素
System.out.println("------------");
System.out.println(c.contains(4));
System.out.println(c.containsAll(c1));
//将集合中元素全部删除
c.clear();
//判断集合是否为空
System.out.println(c.isEmpty());
//判断集合元素个数
System.out.println(c.size());
Collection集合的遍历方式
Collection集合的第一种遍历方式
-
**转数组遍历:**将集合中的数据转到一个数组中,再遍历数组,等于是间接的遍历集合。
-
**集合转为数组的方法:**toArray()
Collection c =new ArrayList();
c.add(new Person("陈一",11));
c.add(new Person("陈二",13));
c.add(new Person("陈三",12));
//遍历方法一:
//先把集合转成数组,用Object超类接收
Object[] o = c.toArray();
//遍历Object数组
for (int i = 0; i < c.size(); i++) {
//强制转型为Person类型
Person p = (Person)o[i];
System.out.println(p.getName());
}
//陈一
//陈二
//陈三
Collection集合的第二种遍历方式
-
使用迭代器遍历集合
迭代:更新换代,一个到下一个
迭代器:用来获取集合中每一个元素的对象
-
**获取迭代器的方式:**通过集合定义的方法来获取:iterator()
-
迭代器对象可以使用的方法:
-
next();
-
hasNext();
-
-
注意事项:
- 虽然每次使用的方法都是next,但是获取的值是不同的
- next方法不仅可以获取下一个元素,而且获取之后,可以将指针指向下一个元素
- hasnext方法只可以判断是否有下一个元素,不能移动指针
- 如果集合中没有下一个元素了,仍然获取,会出现一个异常: NoSuchElementException
Collection c =new ArrayList();
c.add(new Person("陈一",11));
c.add(new Person("陈二",13));
c.add(new Person("陈三",12));
//先获取一个迭代器对象
Iterator i = c.iterator();
//使用hasNext()方法判断是否有下一个元素,如果有返回true否则false
while (i.hasNext()){
//如果有下一个元素,就用next()来获取该元素
System.out.println(i.next());
}
//Person{name='陈一', age=11}
//Person{name='陈二', age=13}
//Person{name='陈三', age=12}
//强转--
Iterator i1 = c.iterator();
while (i1.hasNext()){
//注意:(Person)i1.next()
Person pp = (Person)i1.next();
System.out.println(pp.getName()+"是:"+pp.getAge());
}
//陈一是:11
//陈二是:13
//陈三是:12
Collection集合的第三种遍历方式
-
使用增强for循环遍历
-
增强for循环:
它是JDK5之后出现的,其内部原理Iterator迭代器相同
格式:
for(元素的数据类型 元素名称:集合或者数组名称){
元素名称的使用
}
//for(超类 公共名称:集合名称)
for (Object o1:c){
System.out.println(o1);
}
代码:
Collection c =new ArrayList();
c.add(new Person("陈一",11));
c.add(new Person("陈二",13));
c.add(new Person("陈三",12));
//for(超类 公共名称:集合名称)
for (Object o1:c){
System.out.println(o1);
}
//Person{name='陈一', age=11}
//Person{name='陈二', age=13}
//Person{name='陈三', age=12}
//强转--遍历单个元素值
for (Object o2 : c) {
Person p1 = (Person)o2;
System.out.println((p1.getName())+"是"+(p1.getAge()));
}
//陈一是11
//陈二是13
//陈三是12
List集合
- 特点:
- 属于一个单列集合
- 不能直接创建对象,可以通过实现类创建对象
- 该集合中的元素特点:
- 有序:元素存入的和取出的顺序可以保证一致
- 有索引:每个元素都有自己的一个位置,通过有序的序号来表示这个位置,索引
- 可重复:集合中可以存储相同的元素值
List集合中特殊的方法
- **add(int index, E element) :**往集合中的指定位置添加元素
- **get(int index) :**获取集合中指定元素的值
- **remove(int index) :**删除指定位置的元素
- **set(int index, E element) :**修改集合中指定位置的元素值为element
代码:
并发修改异常解决
出现该异常的原因:
- 一边使用迭代器对象遍历集合,一边使用集合对象增加或者删除元素
ConcurrentModificationException异常
Iterator i =list.iterator();
while (i.hasNext()){ //使用迭代器遍历集合
Object o = i.next();
if (o.equals("chen")){
list.add("AAA"); //集合对象增加元素
}
}
System.out.println(list);
解决方案:【统一】
- 一边使用集合对象遍历,一边使用集合对象增加或者删除
- 一边使用迭代器遍历,一边使用迭代器增加或删除
第一种方式:
-
使用集合遍历:list.size方法和List.get方法
-
使用集合增加:list.add
//解决办法一:使用集合遍历
for (int i = 0; i < list.size()-1; i++) {
Object o = list.get(i);
System.out.print(o+" ");
}
第二种方式:
- **迭代器遍历:**hasnext next
- 迭代器增加:
- 使用父类中获取迭代器对象的方式,没有增加元素的方法,所以要使用List集合特有的获取方式:listIterator()
- 通过这个特有的方式获取的迭代器对象,不仅可以遍历集合,而且有add方法来增加元素。
ListIterator lis =list.listIterator();
while (lis.hasNext()){
Object o = lis.next();
if (o.equals("chen")){
lis.add("AAA");
}
}
List的实现类
分类:
- ArrayList
- LinkedList
ArrayList
特点:
- 底层数组实现,可以表示元素有序
- 查询元素的效率高,增删元素的效率低
- 特点:元素有序,元素有索引,元素可以重复
总结:
- 使用空参构造创建一个ArrayList集合对象,其实底层维护了一个空Object数组
- 当第一次向集合中添加元素,底层先将数组扩容,从0扩容10
- 当10个元素存储之后,继续存储其他元素,底层继续对数组进行扩容,扩容原来的1.5倍,依次类推。
ListedList
-
底层通过双向链表实现,可以保证元素有序
-
查询元素效率低,增删元素效率高
-
使用构造方法创建一个LinkedList对象,底层什么也没有维护(数据是保存在Node对象中,如果没有数据,就不需要创建Node对象)
如果使用该集合对象增加一个元素,那么底层就会新建一个Node对象(节点)来保存该元素的值,以及上一个元素和下一个元素的地址值,如果继续新增元素,那么该新增的元素就是最后一个元素,将上一个元素的last地址改为新元素的地址,也会将新元素的上一个元素地址进行保存
特有方法:【因为linkedList可以记录头部和尾部元素的地址,所以有一些操作头部和尾部元素的方法:】
- addFirst(); 在头部位置添加元素
- addLast(); 在尾部添加元素
- removeFirst(); 删除头部位置的元素
- removeLast(); 删除尾部的元素
- getFirst(); 获取头部元素
- getLast(); 获取尾部元素
总结
-
数组和集合的区别
-
Colllection特点
方法
-
Collection遍历方式:
转数组:toArray
迭代器:iterator
增强for循环
-
List集合特点
-
元素有序 有索引 可以存储重复值
-
add(index ,e) get(index) remove(index) set(index,e)
特有的遍历方式: size() get(index)
-
异常:并发修改异常
使用同一个对象遍历集合,增删元素
-
ArrayList:
底层数组实现,查询快,增删慢
-
LinkedList:
底层双向链表实现,查询慢,增删快
有特殊的方法
-
数组和集合的区别
-
Colllection特点
方法
-
Collection遍历方式:
转数组:toArray
迭代器:iterator
增强for循环
-
List集合特点
-
元素有序 有索引 可以存储重复值
-
add(index ,e) get(index) remove(index) set(index,e)
特有的遍历方式: size() get(index)
-
异常:并发修改异常
使用同一个对象遍历集合,增删元素
-
ArrayList:
底层数组实现,查询快,增删慢
-
LinkedList:
底层双向链表实现,查询慢,增删快
有特殊的方法