一、集合类概述
为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类。
数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
二、Collection接口
2.1、Collection集合的继承体系
2.2、Collection接口概述
Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
2.3、Collection接口成员方法
public static void main(String[] args) {
Collection collection = new ArrayList();
System.out.println(collection);//[]
boolean b1 = collection.add("hello");//添加一个元素
boolean b2 = collection.remove("hello");//删除一个元素
boolean b3 = collection.contains("java");//是否包含
boolean b4 = collection.isEmpty();//是否为空
int size = collection.size();//元素个数
}
public static void main(String[] args) {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("abc1");
c1.add("abc2");
c1.add("abc3");
c1.add("abc4");
c2.add("abc5");
c2.add("abc6");
c2.add("abc7");
c1.addAll(c2);
System.out.println(c1);
System.out.println(c2);
System.out.println("=======================");
boolean b = c1.removeAll(c2);
System.out.println(b);
System.out.println(c1);
System.out.println(c2);
System.out.println("=======================");
boolean b2 = c1.containsAll(c2);
System.out.println(b2);
System.out.println("========================");
boolean b3 = c1.retainAll(c2);
System.out.println(b3);//c1有变化就是true
System.out.println(c1);
System.out.println(c2);
}
public static void main(String[] args) {
Collection c1 = new ArrayList();
c1.add("hello");
c1.add("world");
c1.add("java");
Object[] objects = c1.toArray();
for (int i = 0; i < objects.length; i++) {
String s=(String)objects[i];
System.out.println(s+"==="+s.length());
}
}
public static void main(String[] args) {
Collection c=new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator iterator = c.iterator();
while(iterator.hasNext()){
String s=(String)iterator.next();
System.out.println(s);
}
}
2.4、练习
存储自定义对象并遍历
public static void main(String[] args) {
Student s1 = new Student("张三",23);
Student s2 = new Student("李四",18);
Student s3 = new Student("王五",30);
Collection c=new ArrayList();
c.add(s1);
c.add(s2);
c.add(s3);
Iterator iterator = c.iterator();
while(iterator.hasNext()){
Student s = (Student)iterator.next();
System.out.println(s);
}
}
注意:不要多次使用next();方法,因为每次使用都是访问一个对象
三、List接口
3.1、List接口概述
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。
存储字符串并遍历:
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String s = (String) iterator.next();
System.out.println(s);
}
}
3.2、List接口成员方法
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
list.add(1,123);
System.out.println(list);
list.remove(1);
System.out.println(list);
Object o = list.get(2);
String s = (String)o;
System.out.println(s);
list.set(2,"javaSE");
System.out.println(list);
}
//用成员方法遍历字符串
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
for(int i=0;i<list.size();i++){
String s =(String)list.get(i);
System.out.println(s);
}
}
用自己的迭代器,正反遍历
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
String s =(String)listIterator.next();
System.out.println(s);
}
System.out.println("=============");
while(listIterator.hasPrevious()){
String s = (String)listIterator.previous();
System.out.println(s);
}
}
3.3、ConcurrentModificationException异常
现象:
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
String s = (String)listIterator.next();
if("world".equals(s)){
list.add("javase");
}
}
System.out.println(list);
}
原因:
迭代器是依赖集合存在的,在判断成功后,集合中添加了元素,而迭代器并不能察觉到。
即迭代器遍历元素时,集合不能进行增删。
解决:
(1)迭代器修改元素
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
String s = (String)listIterator.next();
if("world".equals(s)){
listIterator.add("javase");
}
}
System.out.println(list);
}
(2)不使用迭代器遍历(for循环)
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
for(int i=0;i<list.size();i++){
String s =(String)list.get(i);
if("world".equals(s)){
list.add("javase");
}
}
System.out.println(list);
}
3.4、简易图解数据结构
3.5、List的三个子类的特点
ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。