首先呢,给大家讲一下集合的由来:java的思想是面向对象思想,如果想统一的管理所有的对象,就涉及到用容器来储存对象,而对象数组是可以存储对象的,但是数组有一个缺点就是长度固定,为了突破这一限制 ,集合就应运而生了。
数组和集合的优缺点
长度:数组固定,集合可变;
内容:集合只能存储引用类型,数组可以存储基本类型和引用类型。
集合体系
单列集合顶层接口
Collection
|-List有序(存入和取出顺序相同) 存入的元素可以重复 有索引 可以通过索引来操作元素
|-ArrayList 数组结构
|-LinkedList 链表结构
|-Vector 数组结构
|-Set 无序(存入和取出顺序不同) 存入的元素不可以重复
|-HashSet 哈希算法
|-TreeSet 二叉树算法
双列集合
Map
|-HashMap
|-TreeMap
Collection
常用方法:
boolean add(E e):向集合中添加元素e,添加成功返回true,添加失败返回false(List集合永远添加成功 Set集合就有可能添加失败因为Set集合会去掉重复元素)
boolean remove(Object o):删除集合中的元素o,删除成功则true,删除失败则false
void clear():清空集合里面的元素
boolean contains(Object o):集合是否包含元素o,如果包含返回true,如果不包含返回false
boolean isEmpty():判断集合是否为空
int size():集合的长度
集合的长度:c.size();
字符串长度:s.length();
数组的长度:arr.length;
代码演示:
public static void main(String[] args) {
Collection c = new ArrayList(); //父类引用指向子类对象
boolean b1 = c.add("abc"); //添加一个字符串
boolean b2 = c.add(true); //自动装箱new Boolean(true);
boolean b3 = c.add(100); //自动装箱new Integer(100);
boolean b4 = c.add(new Student("张三",23)); //添加一个自定义对象
boolean b5 = c.add("abc"); //添加一个重复的字符串
System.out.println(b1); //true
System.out.println(b2); //true
System.out.println(b3); //true
System.out.println(b4); //true
System.out.println(b5); //true
System.out.println(c);//[abc, true, 100, Student [name=张三, age=23], abc]
//ArrayList的父类重写了Object的toString()
Collection c1 = new ArrayList(); //父类引用指向子类对象
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d");
c1.remove("b"); //删除指定元素
System.out.println(c1); //[a, c, d]
System.out.println(c1.contains("b")); //false 判断是否包含
System.out.println(c1.contains("c")); //true 判断是否包含
System.out.println(c1.size()); //3 长度为3
System.out.println(c1.isEmpty()); //false 不为空
c1.clear(); //清空集合 //清空集合
System.out.println(c1); //[]
}
Object[] toArray():集合转数组 (可以用来遍历)
代码演示:
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(new Student("张三", 23)); //自动类型提升:Object obj = new Student("张三",23);
c.add(new Student("李四", 24));
c.add(new Student("王五", 25));
c.add(new Student("赵六", 26));
Object[] arr = c.toArray(); //将集合转换成数组
for (int i = 0; i < arr.length; i++) {
Student s = (Student)arr[i]; //向下转型
System.out.println(s.getName() + "..." + s.getAge());
}
}
不常用的带All的方法
boolean addAll(Collection c):添加 c里面的所有元素
boolean removeAll(Collection c):删除交集
boolean containsAll(Collection c):是否全部包含
boolean retainAll(Collection<?> c):取交集
迭代器 Iterator
迭代器的原理
Iterator是个接口,是通过集合里面的内部类实现的。迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法。这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部定义自己迭代方式,这样做的好处有二:第一、规定了整个集合体系的遍历方式都是hasNext()和next()方法;第二、代码有底层内部实现,使用者不用管怎么实现的,会用即可。
代码演示:
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(new Student("张三", 23)); //Object obj = new Student("张三",23);
c.add(new Student("李四", 24));
c.add(new Student("王五", 25));
c.add(new Student("赵六", 26));
//获取迭代器
Iterator it = c.iterator();
while(it.hasNext()) {
System.out.println(((Student)it.next()).getName()+" "+
((Student)it.next()).getAge());//如果这样写的话 打印结果为 zhangsan 14 并且报错java.util.NoSuchElementException 因为next()方法调用一次,指针就往后走一次
Student s = (Student)it.next(); //所以一般while循环里面 就出现一次next(),如果想使用多次 请用一个变量接受next()方法的返回值
System.out.println(s.getName()+" "+s.getAge());
}
}
List接口
List的特有方法
void add(int index,E element);在指定的index位置插入element元素
E remove(int index);删除index位置上的元素
E get(int index);获取指定index位置上的元素。可以用来遍历List集合,而且这种遍历方式是List特有的遍历方式
E set(int index,E element);把集合中index位置上的元素用element元素替换
concurrentModificationException:并发修改异常
原因:在用迭代器遍历集合的时候,我们通过集合改变了元素,而迭代器是通过集合得到的,集合发生了改变,而迭代器还是通过原来的集合得到的,所以产生了并发修改异常。
解决:
- 通过迭代器遍历集合的时候,我们通过迭代器来改变集合元素,而这时候原来Iterator没有添加元素的方法,所以就用ListIterator,因为ListIterator里面有add方法
- 通过普通for循环来遍历集合的时候,用集合来改变元素
代码演示:
public static void main(String[] args) {
List list = new ArrayList();
list.add("a"); //Object obj = new String();
list.add("b");
list.add("world");
list.add("c");
list.add("d");
list.add("e");
//报并发修改异常原因:
Iterator it = list.iterator(); //获取迭代器
while(it.hasNext()) { //判断集合中是否有元素
String str = (String)it.next(); //向下转型
if("world".equals(str)) {
//遍历的同时在用集合调用add方法增加元素,并发修改ConcurrentModificationException
list.add("javaee");
}
}
//解决方案一
ListIterator lit = list.listIterator();//获取迭代器(List集合特有的)可以通过hasPrevious()和previous()来往前遍历
while(lit.hasNext()) {
String str = (String)lit.next();//向下转型
if("world".equals(str)) {
lit.add("javaee"); //遍历的同时用迭代器调用add方法添加元素就没问题
}
}
//解决方案二
for (int i = 0; i < list.size(); i++) { //通过普通for循环来遍历集合的时候,用集合来改变元素
String str = (String)list.get(i);
if("world".equals(str)){
list.add("javaee");
}
}
System.out.println(list);
}
ArrayList
基本上都是从List实现的方法,因此没有特有的方法。
案例:ArrayList去除集合中字符串的重复值(字符串的内容相同)
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
list.add("c");
list.add("c");
ArrayList newList = getSingle(list);
System.out.println(newList);
}
/*
* 分析:
* 1,创建新集合
* 2,根据传入的集合(老集合)获取迭代器
* 3,遍历老集合
* 4,通过新集合判断是否包含老集合中的元素,如果包含就不添加,如果不包含就添加
*/
public static ArrayList getSingle(ArrayList list) {
ArrayList newList = new ArrayList<>(); //1,创建新集合
Iterator it = list.iterator(); //2,根据传入的集合(老集合)获取迭代器
while(it.hasNext()) { //3,遍历老集合
Object obj = it.next(); //记录住每一个元素
if(!newList.contains(obj)) { //如果新集合中不包含老集合中的元素
newList.add(obj); //将该元素添加
}
}
return newList;
}
LinkedList
public void addFirst(E e)将指定元素插入此列表的开头。
public void addLast(E e)将指定元素添加到此列表的结尾。
public E removeFirst()移除并返回此列表的第一个元素。
public E removeLast()移除并返回此列表的最后一个元素。
public E getFirst()返回此列表的第一个元素。
public E getLast()返回此列表的最后一个元素。
代码演示:
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addFirst("a");
list.addFirst("b");
list.addFirst("c");
list.addFirst("d");
list.addLast("e");
System.out.println(list.getFirst()); //d
System.out.println(list.getLast()); //e
System.out.println(list.removeFirst()); //d
System.out.println(list.removeLast()); //e
System.out.println(list); //[c, b, a]
}
栈和队列:
栈: 先进后出
队列: 先进先出
Vector
jdk1.0出现1.2并入到List体系,后来被ArrayList替代,所以了解即可。
附:
数组结构:查询快 增删慢
链表结构:查询慢 增删快List的三个儿子的特点
ArrayList:查询快 增删慢 不安全 效率高
LinkedList:查询慢 增删快 不安全 效率高
Vector:查询快 增删慢 安全 效率低
好了集合部分就先说到这了,想了解更多学习知识,请关注微信公众号“阿Q说”,获取更多学习资料吧!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。
网友评论