知识点
Java集合框架支持规则集、线性表、队列和图,他们分别定义在接口Set、List、Quene和Map中。
规则集用于存储一组互不相同的元素。
线性表用于存储一个有序的元素集合。
图(Map)中存储的是键/值对。
Java集合框架中的所有实例类都实现了Cloneable和Serializable接口。所以,它们的实例都是可以复制和可序列化的。
规则集存储的是不重复的元素。若要在集合中存储重复的元素,就需要使用线性表。线性表不仅可以存储重复的元素,而且允许用户指定存储的位置。用户可以通过下标来访问线性表中的元素。
Java集合框架支持三种类型的规则集:散列集HashSet、链式散列集LinkedHashSet和树型集TreeSet。HashSet以一个不可预知的顺序存储元素;LinkedHashSet以元素被插入的顺序存储元素;TreeSet存储已排好的元素。所有方法都继承自Collection接口。
Java集合框架支持两种类型的线性表:数组线性表ArrayList和链表LinkedList。ArrayList是实现List接口的可变大小的数组。ArrayList中的所有方法都是在List接口中定义的。LinkedList是实现List接口的一个链表。除了实现List接口,该类还提供了可从线性表两端提取、插入以及删除元素的方法。
Vector类实现了List接口。Vector类和ArrayList是一样的,所不同的是它所包含的访问和修改向量的方法是同步的。Stack类扩展了Vector类,并且提供了几种对栈进行操作的方法。
Queue接口表示队列。PriorityQueue类为优先队列实现Queue接口。
Collection接口表示存储在规则集或线性表中元素的集合。Map接口将键值映射到元素,键值类似于下标。在List中,下标是整数。而在Map中,键值可以是任意类型的对象。图中不能包含重复的键值。一个键值至多可以对应一个值。Map接口提供了查询、更新、获取值集合和键值集合的方法。
Java集合框架支持三种类型的图:散列图HashMap、链式散列图LinkedHashMap和树形图TreeMap。对于定位一个值、插入一个映射和删除一个映射而言,HashMap是很高效的。LinkedHashMap支持图中的条目排序。HashMap类中的条目是没有顺序的,但LinkedHashMap中的条目可以按某种顺序来获取,该顺序既可以是它们插入图中的顺序(称为插入顺序),也可以是它们最后一次访问的时间顺序,从最早到最晚(称为访问顺序)。对于遍历排好序的键值,TreeMap是高效的。键值可以使用Comparable接口来排序,也可以使用Comparator接口来排序。
01)集合框架(概述)
02)共性方法
- /*
- * 1:add方法的参数类型都是Object。以便于接受任意类型的对象。
- * 2:集合中存储的都是对象的引用(地址)。
- */
- public class CollectionDemo {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- System.out.println("---------------分割线---------------");
- method_2();
- }
- public static void method_1(){
- //创建一个容器。使用Collection接口的子类。ArrayList。
- ArrayList al = new ArrayList();
- //1:添加元素
- al.add("Java01");
- al.add("Java02");
- al.add("Java03");
- al.add("Java04");
- //2:打印集合
- sop("原集合 = " + al);
- sop("原集合 = " + al.clone());
- //3:判断元素。
- sop("判断Java02是否存在 = " + al.contains("Java02"));
- sop("判断集合是否为空 = " + al.isEmpty());
- //3:删除元素
- al.remove("Java03");//删除指定元素。
- al.remove(1);//删除下标为1的元素。
- sop("删除后 = " + al.clone());
- //4:获取个数。集合长度。
- sop("清空前长度 = " + al.size());
- //5:清空集合。
- al.clear();
- sop("清空后集合 = " + al.clone());
- sop("清空后长度 = " + al.size());
- }
- public static void method_2(){
- ArrayList a = new ArrayList();
- a.add("Java01");
- a.add("Java02");
- a.add("Java03");
- a.add("Java04");
- sop("改变前a = " + a);
- ArrayList b = new ArrayList();
- b.add("Java06");
- b.add("Java05");
- b.add("Java04");
- b.add("Java03");
- sop("改变前b = " + b);
- System.out.println("---------------分割线---------------");
- //取交集,a只会保留和b中相同的元素。
- sop(a.retainAll(b));
- sop("改变后a = " + a);
- sop("改变后b = " + b);
- System.out.println("---------------分割线---------------");
- }
- }
03)迭代器——Iterator
- public class CollectionDemo_2 {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_get();
- }
- public static void method_get(){
- ArrayList a = new ArrayList();
- a.add("Java01");//add(Object obj)
- a.add("Java02");
- a.add("Java03");
- a.add("Java04");
- Iterator it_1 = a.iterator();//获取迭代器,用于取出集合中的元素。
- while(it_1.hasNext()){//如果仍有元素可以迭代,则返回 true。
- sop("While: " + it_1.next());//while代码相较for而言显的更少
- }
- System.out.println("-----分割线-----");
- for (Iterator it_2 = a.iterator(); it_2.hasNext();){
- sop("For: " + it_2.next());//细节:for能尽可能的少用内存空间。
- }
- }
- }
04)List集合共性方法
- /*
- * Collection
- * |--List:元素是有序的,元素可以重复。因为该集合体系有索引。
- * |--Set:元素是无序,元素不可以重复。
- *
- * List:特有方法。凡是可以操作角标的方法都是该体系特有的方法。
- *
- * 增:add(index, element):在列表的指定位置插入指定元素。
- * addAll(index, Collection):添加指定 collection 中的所有元素到此列表的结尾。
- * 删:remove(index):移除列表中指定位置的元素。
- * 改:set(index, element):用指定元素替换列表中指定位置的元素。
- * 查:get(index):返回列表中指定位置的元素。
- * subList(from, to):返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
- * listIterator();返回此列表元素的列表迭代器(按适当顺序)。
- * int indexOf(obj):获取指定元素的位置。
- * ListIterator listIterator():
- *
- *
- */
- public class ListDemo {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- }
- public static void method_1(){
- ArrayList a = new ArrayList();
- //添加元素。
- a.add("Java01");
- a.add("Java02");
- a.add("Java04");
- sop("原集合是: " + a);
- //在指定位置添加元素。
- a.add(2, "Java03");
- sop("第一次修改后是: " + a);
- //删除指定位置元素。
- a.remove(3);
- sop("第二次修改后是: " + a);
- //通过下标获取元素。
- sop("get(1): " + a.get(1));
- System.out.println("-----分割线-----");
- //获取所有元素。
- for (int i = 0; i < a.size(); i++)
- System.out.println("a(" + i + ") = " + a.get(i));
- System.out.println("-----分割线-----");
- //迭代器,获取所有元素。
- Iterator it = a.iterator();
- while(it.hasNext())
- sop("next = " + it.next());
- }
- }
- /*
- * List集合特有的迭代器。
- * ListIterator是Iterator的子接口。
- *
- * 在迭代时,不可以通过集合对象的方法操作集合中的元素。
- * 因为会发生ConcurrentModificationException异常。
- *
- * 所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
- * 只能对元素进行判断,取出,删除的操作。
- * 如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
- *
- * 该接口只能通过List集合的listIterator方法获取。
- */
- public class ListDemo_2 {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- System.out.println("----------------------分割线----------------------");
- method_2();
- System.out.println("----------------------分割线----------------------");
- method_3();
- }
- public static void method_3(){
- ArrayList a = new ArrayList();
- //添加元素。
- a.add("Java01");
- a.add("Java02");
- a.add("Java03");
- a.add("Java04");
- sop("原a = " + a);
- for (ListIterator it = a.listIterator(); it.hasNext();){
- sop("(前面是否有元素)hasPrevious = " + it.hasPrevious());//判断前面是否有元素。
- Object obj = it.next();
- if (obj.equals("Java01"))
- it.add("Java添加");
- if (obj.equals("Java03"))
- it.set("Javahah");
- sop("(打印元素)obj = " + obj);
- System.out.println("------------------------------------------------");
- }
- sop("修改后a = " + a);
- }
- public static void method_2(){
- ArrayList a = new ArrayList();
- //添加元素。
- a.add("Java01");
- a.add("Java02");
- a.add("Java03");
- a.add("Java04");
- //在迭代过程中,准备添加或者删除元素。
- for (Iterator it = a.iterator(); it.hasNext();){
- // sop("Next = " + it.next());
- Object obj = it.next();//取出元素。
- if(obj.equals("Java01"))
- it.remove();//将Java01的引用在集合中删除。
- sop("obj = " + obj);
- }
- sop("a = " + a);
- }
- public static void method_1(){
- ArrayList a = new ArrayList();
- //添加元素。
- a.add("Java01");
- a.add("Java02");
- a.add("Java03");
- a.add("Java04");
- //通过indexOf获取对象的位置。
- sop("indexOf = " + a.indexOf("Java03"));
- //通过指定下标获取集合中的元素。
- List sup = a.subList(1, 3);
- sop("sup = " + sup);
- }
- }
06)List集合具体对象的特点
- /*
- * Collection
- * |--List:元素是有序的,元素可以重复。因为该集合体系有索引。
- * |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
- * |--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
- * |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。
- * |--Set:元素是无序,元素不可以重复。
- */
07)Vector中的枚举
- /*
- * 枚举就是Vector特有的取出方式。
- * 发现枚举和迭代器很像。其实枚举和迭代器是一样的。
- *
- * 因为枚举的名称以及方法的名称都过长。所以枚举被迭代器取代了。
- */
- public class VectorDemo {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- method_2();
- }
- public static void method_1(){
- Vector v1 = new Vector();
- v1.add("Java01");
- v1.add("Java02");
- v1.add("Java03");
- v1.add("Java04");
- sop("v1 = " + v1);
- System.out.println("-----------------------------------------");
- for (ListIterator it = v1.listIterator(); it.hasNext();){
- sop("it = " + it.next());//取数据
- }
- System.out.println("-----------------------------------------");
- }
- public static void method_2(){
- Vector v2 = new Vector();
- v2.add("Java01");
- v2.add("Java02");
- v2.add("Java03");
- v2.add("Java04");
- sop("v2 = " + v2);
- System.out.println("-----------------------------------------");
- for (Enumeration<E> en = v2.elements(); en.hasMoreElements();){//早期方式。
- sop("en = " + en.nextElement());
- }
- System.out.println("-----------------------------------------");
- }
- }
08)LinkedList
- /*
- * LinkedList特有方法:1.6之前。
- * addFirst():将指定元素插入此列表的开头。
- * addLast():将指定元素添加到此列表的结尾。
- * getFirst():返回此列表的第一个元素。
- * getLast():返回此列表的最后一个元素。
- * :获取元素,但不删除元素。长度不变。
- * :如果集合中没有元素,会出现NoSuchElementException。
- * removeFirst():移除并返回此列表的第一个元素。
- * removeLast():移除并返回此列表的最后一个元素。
- * :获取元素,并且删除元素。
- * :如果集合中没有元素,会出现NoSuchElementException。
- *
- * 1.6开始出现的替代:
- * offerFirst():
- * offerLast():
- * peekFirst():
- * peekLast():
- * poolFirst():
- * poolLast():
- */
- public class LinkedListDemo {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- method_2();
- }
- public static void method_1(){
- LinkedList link = new LinkedList();
- link.addFirst("(2)Java01");
- link.addLast("(3)Java02");
- link.addFirst("(1)Java03");//将元素添加到此列表的开头。
- link.addLast("(4)Java04");//将元素添加到此列表的尾部。
- sop("add = " + link);
- sop("getFirst = " + link.getFirst());
- sop("getLast = " + link.getLast());
- System.out.println("------------------------------------------------------------------");
- }
- public static void method_2(){
- LinkedList link = new LinkedList();
- link.offerFirst("(1)Java01");//将元素添加到此列表的开头。
- link.offerFirst("(2)Java02");
- link.offerFirst("(3)Java03");
- link.offerFirst("(4)Java04");
- sop("(原)add = " + link);
- sop("remove(0) = " + link.remove(0));//获取下标为0的元素,并且删除该元素。
- sop("(改)add = " + link);
- System.out.println("------------------------------------------------------------------");
- for(; !link.isEmpty(); ){
- sop("jdk1.6 poolLast = " + link.pollLast());
- }
- }
- }
09)LinkedList(练习)
- /*
- * 使用LinkedList模拟一个堆栈或者队列数据结构。
- * 堆栈:先进后出。如同一个杯子。
- * 队列:先进先出。如同一根水管。
- */
- public class LinkedListTest {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- useDuiLie();
- System.out.println("-----------------------");
- uesDuiZhan();
- }
- public static void useDuiLie(){
- DuiLie dl = new DuiLie();
- dl.dlAdd("Java01");
- dl.dlAdd("Java02");
- dl.dlAdd("Java03");
- dl.dlAdd("Java04");
- while (!dl.isNull())
- sop("队列: " + dl.dlGet());
- }
- public static void uesDuiZhan(){
- DuiZhan dz = new DuiZhan();
- dz.dzAdd("Java01");
- dz.dzAdd("Java02");
- dz.dzAdd("Java03");
- dz.dzAdd("Java04");
- while (!dz.isNull())
- sop("堆栈: " + dz.dzGet());
- }
- }
- class DuiLie{
- private LinkedList link;
- DuiLie(){
- link = new LinkedList();
- }
- public void dlAdd(Object obj){
- link.offerFirst(obj);//添加元素在队列最开头。
- }
- public Object dlGet(){
- return link.pollLast();//从队列尾部开始取元素。
- }
- public boolean isNull(){
- return link.isEmpty();
- }
- }
- class DuiZhan{
- private LinkedList link;
- DuiZhan(){
- link = new LinkedList();
- }
- public void dzAdd(Object obj){
- link.offerFirst(obj);//添加元素在队列最开头。
- }
- public Object dzGet(){
- return link.pollFirst();//从队列开头开始取元素。
- }
- public boolean isNull(){
- return link.isEmpty();
- }
- }
10)ArrayList(练习一)
- /*
- * 去除ArrayList中重复的元素。
- */
- public class ArrayListTest {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- }
- public static void method_1(){
- ArrayList al = new ArrayList();
- al.add("Java0");
- al.add("Java1");
- al.add("Java3");
- al.add("Java2");
- al.add("Java1");
- al.add("Java2");
- sop("Al = " + al);
- sop("show(NewAl) = " + show(al));
- }
- public static List show(ArrayList al){
- ArrayList newAl = new ArrayList();//创建一个新集合。
- for (Iterator<E> it = al.iterator(); it.hasNext();){
- Object obj = it.next();//依次打印元素
- if (!newAl.contains(obj))//如果新集合中包不含有原集合的元素
- newAl.add(obj);//添加元素。
- }
- return newAl;//返回新集合。
- }
- }
11)ArrayList(练习二)
- /*
- * 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
- * 比如:存人元素。同姓名,同年龄,视为同一元素。
- *
- * 思路:
- * 1:对人描述,将数据封装人对象。
- * 2:定义容器,将人存入。
- * 3:取出。
- *
- * List集合判断元素是否相同,依据的是元素的equals方法。
- */
- public class ArrayListTest_2 {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- method_2();
- }
- public static void method_2(){
- ArrayList al = new ArrayList();
- al.add(new Person("汤姆01号", 10));
- al.add(new Person("汤姆02号", 10));
- al.add(new Person("汤姆01号", 10));
- al.add(new Person("杰瑞01号", 11));
- al.add(new Person("杰瑞02号", 11));
- al.add(new Person("杰瑞01号", 11));
- List al2 = show(al);
- for (Iterator it = al2.iterator(); it.hasNext();){
- Person p = (Person)it.next();
- sop(p.getName() + " " + p.getAge());
- }
- }
- public static void method_1(){//示例
- ArrayList al = new ArrayList();
- al.add(new Person("汤姆01号", 10));
- al.add(new Person("汤姆02号", 10));
- al.add(new Person("汤姆01号", 10));
- al.add(new Person("杰瑞01号", 11));
- al.add(new Person("杰瑞02号", 11));
- al.add(new Person("杰瑞01号", 11));
- for (Iterator it = al.iterator(); it.hasNext(); ){
- Person p = (Person)it.next();
- sop(p.getName() + " " + p.getAge());
- }
- System.out.println("------------------------------");
- }
- public static List show(ArrayList al){
- ArrayList newAl = new ArrayList();//创建一个新集合。
- for (Iterator it = al.iterator(); it.hasNext();){
- Object obj = it.next();//依次打印元素
- if (!newAl.contains(obj))//如果新集合中包不含有原集合的元素
- newAl.add(obj);//添加元素。
- }
- return newAl;//返回新集合。
- }
- }
- class Person{
- private String name;
- private int age;
- Person(String name, int age){
- this.name = name;
- this.age = age;
- }
- public boolean equals(Object obj){
- if (!(obj instanceof Person))
- return false;
- Person p = (Person)obj;
- return this.name.equals(p.name) && this.age == p.age;
- }
- public String getName(){
- return name;
- }
- public int getAge(){
- return age;
- }
- }
12)HashSet
- /*
- * |--Set:元素是无序(存入顺序和元素的位置不一致),元素不可以重复。
- * |--HashSet:底层的数据结构是哈希表。
- * |--TreeSet:
- *
- * Set集合的功能和Collection接口的功能是一致的。
- */
- public class HashSetDemo {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- }
- public static void method_1(){
- HashSet hs = new HashSet();//创建一个HashSet集合。无序。
- sop(hs.add("Java01"));//判断为true
- sop(hs.add("Java01"));//判断为false
- hs.add("Java02");
- hs.add("Java03");
- sop(hs.add("Java03"));//判断为false
- hs.add("Java04");
- for (Iterator it = hs.iterator(); it.hasNext();){
- sop(it.next());
- }
- }
- }
13)HashSet存储自定义对象——复写hashCode和equals方法
- /*
- * |--Set:元素是无序(存入顺序和元素的位置不一致),元素不可以重复。
- * |--HashSet:底层的数据结构是哈希表。
- * HashSet是如何保证元素唯一性的呢?
- * 是通过元素的两个方法,hasCode和equals来完成的。
- * 如果元素的hashCode值相同,才会判断equals是否为true。
- * 如果hashCode的值不同,就不会判断equals。
- * |--TreeSet:
- *
- * Set集合的功能和Collection接口的功能是一致的。
- */
- public class HashSetTest_1 {
- public static void sop(Object obj){
- System.out.println(obj);
- }
- public static void main(String[] args) {
- method_1();
- }
- public static void method_1(){
- HashSet hs = new HashSet();
- hs.add(new Person_2("汤姆(1)", 10));
- hs.add(new Person_2("汤姆(2)", 10));
- sop(hs.add(new Person_2("汤姆(2)", 10)));//判断为false
- hs.add(new Person_2("汤姆(3)", 10));
- sop(hs.add(new Person_2("汤姆(3)", 10)));//判断为false
- hs.add(new Person_2("汤姆(4)", 10));
- for (Iterator it = hs.iterator(); it.hasNext();){
- Person_2 p = (Person_2)it.next();
- sop(p.getName() + " :: " + p.GetAge());
- }
- }
- }
- class Person_2{
- private String name;
- private int age;
- Person_2(String name, int age){
- this.name = name;
- this.age = age;
- }
- public int hashCode(){//细节:复写hashCode。集合底层内部自动调用。
- return name.hashCode() + age * age;
- }
- public boolean equals(Object obj){//细节:复写equals。集合底层内部自动调用。
- if (!(obj instanceof Person_2))
- return false;
- Person_2 p = (Person_2)obj;
- return this.name.equals(p.name) && this.age == p.age;
- }
- public String getName(){
- return name;
- }
- public int GetAge(){
- return age;
- }
- }<span style="white-space:pre"> </span>
14)HashSet判断和删除的依据
对于元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。