一、集合概述
1.集合的由来?
Java是面向对象的,使用过程中一定操作很多对象,进行存储,而存储需要容器(数组和StringBuffer),但是数组的长度固定,
所以不适合做变化的需求,Java就提供了集合供我们使用。
2.集合和数组的区别?
1)长度区别
数组固定
集合可变
2)内容区别
数组可以是基本类型,也可以是引用类型
集合只能是引用类型
3)元素内容
数组只能存储同一种类型
集合可以存储不同类型(其实集合一般存储的也是同一种类型
3.集合的继承体系结构
由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,但是它们都是要提供存储和遍历功能的,
我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。
Collection
|--List
|--ArrayList
|--Vector
|--LinkedList
|--Set
|--HashSet
|--TreeSet
二、Collection
1.Collection的功能概述
1)添加功能:
boolean add(Object obj):添加一个元素
boolean addAll(Collection c):添加一个集合的元素
2)删除功能:
void clear():移除所有元素
boolean remove(Object o):移除一个元素
boolean removeAll(Collection c):移除一个集合的元素(所有)
3)判断功能:
boolean contains(Object o):判断集合中是否包含指定的元素
boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(所有)
boolean isEmpty():判断集合是否为空
4)获取功能:Iterator<E> iterator()
5)长度功能:int size()
6)交集:boolean retainAll(Collection c)
7)把集合转数组:Object[] toArray()
2.Collection集合的遍历
1)把集合转数组:利用toArray()然后遍历数组即可
2)迭代器(集合专用方式)
3.迭代器
1)是集合的获取元素的方式。
2)是依赖于集合而存在的。
3)迭代器的原理:
利用Object next():获取元素,并移动到下一个位置。
利用boolean hasNext()判断是否可以继续迭代,如果仍有元素可以迭代,则返回 true。
NoSuchElementException:没有这样的元素,代表找到最后了。
4.Collection集合的案例(遍历方式 迭代器)
集合的操作步骤:
1)创建集合对象
2)创建元素对象
3)把元素添加到集合
4)遍历集合
例:存储字符串并遍历
import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; public class CollectionDemo { public static void main(String[] args) { // 创建集合对象 Collection c = new ArrayList(); // 创建并添加元素 c.add("hello"); c.add("world"); c.add("java"); // 遍历集合 Iterator it = c.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } } }
三、List
1.List的特点
List是Collection的子接口,但是是有序(存储顺序和取出顺序一致)的,可重复的。
2.List的特有功能
1)添加功能:void add(int index,Object element):在指定位置添加元素
2)删除功能:Object remove(int index):根据索引删除元素,返回被删除的元素
3)获取功能:Object get(int index):获取指定位置的元素
4)迭代器功能:ListIterator listIterator():List集合特有的迭代器
5)修改功能:Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
3.List集合的特有遍历功能
由size()和get()结合。
例:
4.列表迭代器的特有功能// 创建集合对象 List list = new ArrayList(); // 创建并添加元素 list.add("hello"); list.add("world"); list.add("java"); // 遍历集合 Iterator it = list.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } System.out.println("----------"); for (int x = 0; x < list.size(); x++) { String s = (String) list.get(x); System.out.println(s); }
可以逆向遍历,但是要先正向遍历,所以无意义,基本不使用。
5.常见数据结构
1)栈 先进后出
2)队列 先进先出
3)数组 查询快,增删慢
4)链表 查询慢,增删快
6.注意事项
1)并发修改异常
A:出现的现象:迭代器遍历集合,集合修改集合元素
B:原因:迭代器是依赖于集合的,而集合的改变迭代器并不知道。
C:解决方案
a:迭代器遍历,迭代器修改(ListIterator):元素添加在刚才迭代的位置
b:集合遍历,集合修改(size()和get()):元素添加在集合的末尾
2)List集合的案例(遍历方式 迭代器)
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /* * 列表迭代器: * ListIterator listIterator():List集合特有的迭代器 * 该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。 * * 特有功能: * Object previous():获取上一个元素 * boolean hasPrevious():判断是否有元素 * * 注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。 */ public class ListIteratorDemo { public static void main(String[] args) { // 创建List集合对象 List list = new ArrayList(); list.add("hello"); list.add("world"); list.add("java"); // ListIterator listIterator() ListIterator lit = list.listIterator(); // 子类对象 // while (lit.hasNext()) { // String s = (String) lit.next(); // System.out.println(s); // } // System.out.println("-----------------"); // System.out.println(lit.previous()); // System.out.println(lit.previous()); // System.out.println(lit.previous()); // NoSuchElementException // System.out.println(lit.previous()); while (lit.hasPrevious()) { String s = (String) lit.previous(); System.out.println(s); } System.out.println("-----------------"); // 迭代器 Iterator it = list.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } System.out.println("-----------------"); } }
四、List的子类
1.List的子类特点
1)ArrayList:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
2)Vector:
底层数据结构是数组,查询快,增删慢
线程安全,效率低
3)LinkedList:
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
2.List子类的使用:
使用时看需求选取对应的集合:
1)安全性
要:Vector
不要:ArrayList或者LinkedList
2)查询增删情况
查询多;ArrayList
增删多:LinkedList
什么都不知道,就用ArrayList。
3.ArrayList,没有特有功能需要学习
4.Vector
1)有特有功能
A:添加
public void addElement(E obj) 相当于add()
B:获取
public E elementAt(int index) 相当于get()
public Enumeration<E> elements() 相当于iterator()
2)案例
Vector存储字符串并遍历
import java.util.Enumeration; import java.util.Vector; /* * Vector的特有功能: * 1:添加功能 * public void addElement(Object obj) -- add() * 2:获取功能 * public Object elementAt(int index) -- get() * public Enumeration elements() -- Iterator iterator() * boolean hasMoreElements() hasNext() * Object nextElement() next() * * JDK升级的原因: * A:安全 * B:效率 * C:简化书写 */ public class VectorDemo { public static void main(String[] args) { // 创建集合对象 Vector v = new Vector(); // 添加功能 v.addElement("hello"); v.addElement("world"); v.addElement("java"); // 遍历 for (int x = 0; x < v.size(); x++) { String s = (String) v.elementAt(x); System.out.println(s); } System.out.println("------------------"); Enumeration en = v.elements(); // 返回的是实现类的对象 while (en.hasMoreElements()) { String s = (String) en.nextElement(); System.out.println(s); } } }
5.LinkedList
1)有特有功能
A:添加
addFirst()
addLast()
B:删除
removeFirst()
removeLast()
C:获取
getFirst()
getLast()
2)案例
LinkedList存储字符串并遍历
import java.util.LinkedList; /* * LinkedList的特有功能: * A:添加功能 * public void addFirst(Object e) * public void addLast(Object e) * B:获取功能 * public Object getFirst() * public Obejct getLast() * C:删除功能 * public Object removeFirst() * public Object removeLast() */ public class LinkedListDemo { public static void main(String[] args) { // 创建集合对象 LinkedList link = new LinkedList(); // 添加元素 link.add("hello"); link.add("world"); link.add("java"); // public void addFirst(Object e) // link.addFirst("javaee"); // public void addLast(Object e) // link.addLast("android"); // public Object getFirst() // System.out.println("getFirst:" + link.getFirst()); // public Obejct getLast() // System.out.println("getLast:" + link.getLast()); // public Object removeFirst() System.out.println("removeFirst:" + link.removeFirst()); // public Object removeLast() System.out.println("removeLast:" + link.removeLast()); // 输出对象名 System.out.println("link:" + link); } }
五、泛型以及一些JDK5后的新特性
1.泛型概述
是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。
2.格式:
<数据类型>
注意:该数据类型只能是引用类型。
3.好处:
1)把运行时期的问题提前到了编译期间
2)避免了强制类型转换
3)优化了程序设计,解决了黄色警告线问题,让程序更安全
4.泛型细节
1)Object类型作为任意类型的时候,在向下转型的时候,会隐含一个转型问题,所以Java在JDK5后引入了泛型,提高程序的安全性。
出现了以下几种泛型使用方法
A:泛型类
public class ObjectTool<T> { private T obj; public T getObj() { return obj; } public void setObj(T obj) { this.obj = obj; } }
B:泛型方法 public <T> void show(T t)
C:泛型接口
public interface Inter<T> { public abstract void show(T t); }
2)泛型高级通配符
?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E:向下限定,E及其子类
? super E:向上限定,E极其父类
3)泛型使用环境:一般是在集合中使用。
5.增强for循环
1)是for循环的一种
2)格式:
for(元素的数据类型 变量名 : 数组或者Collection集合的对象) {
使用该变量即可,该变量其实就是数组或者集合中的元素。
}
3)好处:简化了数组和集合的遍历
4)弊端:增强for循环的目标不能为null。建议在使用前,先判断是否为null。
6.静态导入
1)可以导入到方法级别的导入
2)格式:import static 包名....类名.方法名;
3)注意事项:
A:方法必须是静态的
B:如果多个类下有同名的方法,就不好区分了,还得加上前缀,所以一般不使用静态导入。
7.可变参数
1)如果在写方法的时候,参数个数不明确,就应该定义可变参数。
2)格式:修饰符 返回值类型 方法名(数据类型... 变量) {}
3)注意:
A:该变量其实是一个数组名
B:如果一个方法有多个参数,并且有可变参数,可变参数必须在最后
4)Arrays工具类的一个方法
asList()把数组转成集合。但是这个集合的长度不能改变。
8.泛型案例
import java.util.ArrayList; import java.util.Iterator; public class GenericDemo { public static void main(String[] args) { // 创建 ArrayList<String> array = new ArrayList<String>(); // 添加元素 array.add("hello"); array.add("world"); array.add("java"); // array.add(new Integer(100)); // array.add(10); // JDK5以后的自动装箱 // 等价于:array.add(Integer.valueOf(10)); // 遍历 Iterator<String> it = array.iterator(); while (it.hasNext()) { // ClassCastException // String s = (String) it.next(); String s = it.next(); System.out.println(s); } for (String s : array) { System.out.println(s); } // 看下面这个代码 // String[] strArray = new String[3]; // strArray[0] = "hello"; // strArray[1] = "world"; // strArray[2] = 10; } }