(十)Core Java 集合框架 -01 (101)
目录 :
1 ) . 集合框架(体系概述)2 ) . 集合框架(共性方法)3 ) . 集合框架(迭代器)4 ) . 集合框架(List集合共性方法)5 ) . 集合框架(ListIterator)6 ) . 集合框架(List集合具体对象的特点)7 ) . 集合框架(Vector中的枚举)8 ) . 集合框架(LinkedList)9 ). 集合框架(LinkedList练习)10 ).集合框架(ArrayList )11 ).集合框架(ArrayList练习)12 ).集合框架(ArrayList )13 ).集合框架(HashSet )14 ).集合框架(HashSet存储自定义对象 )15 ).集合框架(HashSet判断和删除的依据 )
一. 集合框架(体系概述)
1 ) . 引入 : java中最重要的事务是对象,数据多了封装成对象,对象多了封装成集合或者数组2 ) . 简述 :
2.1 为什么会出现集合类?
[1] 面向对象语言对事物的体现都是以对象的形式,因此为了方便对多个对象操作,就对对象进行储存,集合就是存储对象的常用方式之一
2.2 数组和集合类同是容器,有何不同?
[1] 相同点在于数组和集合都是用来做存储的[2]不同点在于数组长度固定,集合长度不固定;数组可存基本数据类型,集合只能存对象;数组类型初始化后固定,但集合类型初始化后不固定
2.3 集合类的特点 :
[1] 集合只能用于存储对象[2]集合的长度是可变的[3] 集合可以存储不同类型的对象
3 ) . 为何会出现如此多的容器呢?3.1 因为每个容器对数据的存储方式都有不同,这个存储方式称之为 :数据结构
4 ) . 集合框架体系 :
小结 :1. 容器当中的共性抽取形成体系,最终出来集合框架2. 参阅顶层,创建底层,一来是因为底层是接口或抽象类,不可创建对象,二来 底层实现的方法多一些3. 数据在内存中的构成情况和存储方式又称为数据结构
二. 集合框架(共性方法)
1 ) . 详情看代码块内:import java.util.*;/*引入:[1] add方法的参数类型是Object,以便于接收任意类型对象[2] 集合中存储的都是对象的引用(地址)1.通过rationAll()取集合交集2.通过removeAll()删集合共通3.通过clear()清空集合4.通过contains()判断集合内元素是否存在5.通过isEmpty()判断集合内是否为空*/class CollectionDemo{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){method_01();}public static void method_01(){//创建第一个集合ArrayList ary1 = new ArrayList();//1.添加元素ary1.add("Hello1");ary1.add("Hello2");ary1.add("Hello3");ary1.add("Hello4");//创建第二个集合ArrayList ary2 = new ArrayList();//2.添加元素ary2.add("Hello1");ary2.add("Hello2");ary2.add("Hello7");ary2.add("Hello8");// ary1.retainAll(ary2); //取出ary1与ary2之间的交集部分,并且将交集放入ary1ary1.removeAll(ary2); //删除ary1中与ary2相同的部分,留下Ary1中的内容sop("ary:"+ary1);}public static void method_base(){//使用collection接口的实现类arraylist创建一个集合容器ArrayList ary = new ArrayList();//1.添加元素ary.add("Hello1");ary.add("Hello2");ary.add("Hello3");ary.add("Hello4");//打印原集合sop(ary);//2.删除元素//ary.remove("Hello1"); -->删除指定元素//ary.clear(); -->清空所有元素//3.判断元素sop("判断hello1是否存在:"+ary.contains("Hello1")); //-->true存在sop("判断该集合是否为空:"+ary.isEmpty()); //-->不为空//获取个数,也就是集合长度//sop(ary.size());//打印现集合sop(ary);//System.out.println("Hello World");}}
小结 :1. 集合类在java的工具包中2. 因为java中的多态的体现,因此Object是多种存在形态的最大上帝类,可代替所有的参数3. 集合内存对象,在堆内存上 , 实际存的是内存地址
三. 集合框架(迭代器)
1 ) . 迭代器
1.1 当需要取集合内元素时,通过内部类最方便,因此interator就是定义在集合中的内部类,用来取元素1.2 同时集合分多种,将获取(判断,取出)这个共性抽取标准化形成接口,让多个集合实现,就统一规范了获取方式1.3 每个集合容器的数据结构不同,取出方式不同,则实现接口后再定义自己的具体细节部分
小结 : 迭代器就是封装了获取的功能,为所有的集合提供了标准化的获取方式,对集合提供的方法是interator();
2 ) . 迭代器与集合的关系?
2.1 抓娃娃--> 集合是装娃娃的大箱子, 集合内的元素是大箱子内的娃娃,迭代器是 大箱子内上边的夹子 ; 不同的夹子就是在不同集合中不同的迭代器2.2 迭代器在集合中的底层实现是 通过内部类的方式实现的
3 ) . Demo :import java.util.*;/*什么是迭代器? 指用来取出集合中元素的方式常用方法 : -->然后通过for循环或者wile循环 ; for优于while -->因为局部变量用完释放的原因1.iterator() --获取一个迭代器2.hastNext() --->判断是否还有元素,有则返回true,否则false3.next() -->获取下一个元素*/class IteratorDemo{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){method_01();}public static void method_01(){//创建第一个集合ArrayList ary1 = new ArrayList();//1.添加元素ary1.add("Hello1");ary1.add("Hello2");ary1.add("Hello3");ary1.add("Hello4");//迭代输出方式一/* Iterator it =ary1.iterator();while(it.hasNext()){sop(it.next());} *///迭代输出方式二for(Iterator it = ary1.iterator();it.hasNext();){sop(it.next());}//方式二优于第一种方法是因为方式二没有在内存中留有对象残余,it在for循环结束后就释放了}}小结 :1. 接口的引用是指向自己的子类对象2. 集合中存在着元素,操作元素最便捷的方式就是在集合中定义类,通过内部类实现
四. 集合框架(List集合共性方法)
1 ) .1.1 List中有两种移除方法 :
[1] 一种是按照对象的方式移除[2] 一种是按照指定元素的位置移除1.2 体系 : Collection[1] List : 元素是有序的,元素可以重复,因为该集合体系有索引 --> 有索引在内存中中一个索引占一份[2] set : 元素是无序的,元素可重复 -->意味着在内存中 有所个索引指向一个元素的情况
2 ) . Text :import java.util.*;/*List : 特有方法 -->凡是可以操作角标的方法都是该体系特有的方法1.增add(index,element);addAll(index,Collection);2.删remove(index);3.改set(index,element);4.查get(index);subList(from,to);listIterator();*/class IteratorDemo1{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){//实例化一个arrayList集合类ArrayList li = new ArrayList();//1.添加元素li.add("ASD");li.add("FGH");li.add("JKL");sop("li="+li);//1.向某个坐标添加元素//li.add(2,"QQ");//2.修改某坐标的元素//li.set(1,"ZS");//3.删除元素//li.remove(1);//4.查看某坐标元素//sop("get<1>="+li.get(1));//4.查看某区域坐标元素-->包含头不包含尾//sop("get<1-3>="+li.subList(1,3));//4.迭代集合内所有元素,方式一/* for(int i=0; i<li.size();i++){sop("li="+li.get(i));} *///4.迭代集合内所有元素,方式二for(Iterator it =li.iterator();it.hasNext();){sop("li="+it.next());}}}3 ) . 每个集合都有CRUD操作,只是实现方式各有不同,会再原功能名上加上自己的名字标识 ,例如 ArrayList的迭代器是 ListIterator;小结 :1. 每个集合当中都有属于自己的迭代器,List中的迭代器是listInterator2. 一般情况下,凡是参数带角标(index)的都是特有方法3. 数组有长度,集合有大小
五. 集合框架(ListIterator)
1 ) . Iterator接口只有三个方法,hasNext(),next(),remove();有局限性,因此被实现细化了功能,接口是ListIterator2 ) . 区分 :
2.1 方法
[1] iterator接口方法 --> hasNext(),next(),remove();[2] ListIterator 接口方法 --> 除了上边三个, 还有add(); previous(); set() ; 等等
2.2 关系 :
[1] ListIterator继承了Iterator
3 ) . Demo :import java.util.*;/**/class IteratorDemo2{//输出方法public static void sop(Object obj){System.out.println(obj);}public static void method(){//实例化一个arrayList集合类ArrayList li = new ArrayList();//1.添加元素li.add("ASD");li.add("FGH");li.add("JKL");sop("li="+li);/* Iterator it = li.iterator();//1.迭代集合内所有元素并指定删除while(it.hasNext()){Object obj = it.next();if(obj=="ASD")it.remove();// sop("li"+it.next());} *///2.迭代集合内所有元素并指定删除for(Iterator it =li.iterator();it.hasNext();){//将下一个值赋给objectObject obj = it.next();//判断值是否存在,存在则删除if(obj=="ASD")it.remove();}// sop("li="+li);//3.通过indexOf获取元素的位置int index = li.indexOf("ASD");//3.获取范围坐标1-2的元素List sub =li.subList(1,2);sop("获取ASD的位置="+index);sop("获取范围坐标1-2的元素="+sub);}//主方法public static void main(String args[]){//实例化一个arrayList集合类ArrayList li = new ArrayList();//1.添加元素li.add("ASD");li.add("FGH");li.add("JKL");sop("li="+li);//在遍历过程中做修改/删除/增加for(ListIterator lit = li.listIterator(); lit.hasNext();){Object obj = lit.next();if(obj=="ASD")// lit.set("QQQ");// lit.remove();// lit.add("123");}sop("li="+li);}}
小结 :1. 对同一个集合不能使用两种方式同时进行操作2. List元素可以增删改查的原因是它带有角标3. hasNext()是正向判断下一个角标有没有元素,而previous()是逆向判断上一个角标有没有元素,一个正向遍历,一个逆向遍历4. listIterator最大的优势在于可以在集合的遍历过程中进行crud操作
六. 集合框架(List集合具体对象的特点)
1 ) . 体系 :
1.1List
[1] ArrayList --> 底层的数据结构使用的是数组结构 -->特点是查询很快 ,但是增删稍慢 ,另外线程不同步[2] LinkList --> 底层的数据结构使用的是链表数据结构 -->特点是 增删速度快,查询稍慢[3] Vector -->底层的数据结构使用的是数组结构 --> 特点就是 CRUD都超慢, 已被 ArrayList所替代 , 线程同步1.2 ArrayList与LinkList 数据结构图解
小结 :1. 可变数组长度是通过不断NEW数组产生的,ArrayList的底层就是可变数组长度 ,当超出10元素则是 50%的延长,而 vertor 是100%延长2. ArrayList替代了Vector , ArrayList常用于查找, LinkList常用于增删
七. 集合框架(Vector中的枚举)
1 ) . 枚举与迭代器的区别?
1.1 共同点 : 功能相同都是用来迭代数据的,只是一个用在vector集合上,一个用在ArrayList,LinkList...等上,iterator替代了vector1.2 不同点 : 枚举先出来,是来前辈,只是被取代了嘛.哈哈
2 ) . Demo :import java.util.*;/*枚举就是vector特有的取出方式,枚举与迭代器功能一样而枚举的名称以及方法名过长,后期被迭代器取代,但IO流时还需用到枚举*/class VectorDemo4{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){//实例化一个vector集合类Vector ve = new Vector();//1.添加元素ve.add("ASD");ve.add("FGH");ve.add("JKL");//通过枚举的方式遍历for(Enumeration e = ve.elements();e.hasMoreElements();){sop(e.nextElement());}sop("ve="+ve);}}小结 :1. 除了vector中有迭代方式-枚举需要在IO流时用到之外,其它没什么优势了
八. 集合框架(LinkedList)
1 ) . 几种用在for或while循环判定中的条件?
1.1 判定集合是否为空1.2.判定集合的长度1.3 判定数组的长度1.4 判定下一个是否有值
小结: 但凡返回的是boolean类型的大多都可做判定2 ) . Demo:import java.util.*;/*LinkedList:特有方法addFirst();addLast();getFirst();getLast();获取元素,但不删除元素,若集合中没有元素则会抛出NoSuchElementException异常removeFirst();removeLast();获取元素,但是元素被删除,若集合中没有元素,则会抛出NoSuchElementException异常在JDK1.6出现了替代方法offerFisrst();offerLast();peekFrist();peekLast();获取元素,但不删除元素,若 没有元素,会返回nullpoolFirst();poolLast();获取元素,但是元素被删除,若集合中没有元素,则返回null*/class LinkedListDemo{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){LinkedList lk = new LinkedList();//先进后出lk.addFirst("day01");lk.addFirst("day02");lk.addFirst("day03");lk.addFirst("day04");//sop("lk="+lk);//后进先出/* lk.addLast("day01");lk.addLast("day02");lk.addLast("day03");lk.addLast("day04");sop("lk="+lk); *///获取并删除第一个元素//sop(lk.removeFirst());//获取但不删除第一个元素//sop(lk.getFirst());//获取集合中的元素while(!lk.isEmpty()){sop(lk.removeLast());}}}小结 :1. LinkedList常用方法在以上Demo中,用时自查2. LinkedList中有先进后出,后进先出的原则,在使用从第一位添加和从倒数第一位添加时会出现3. NoSuchElementException另外这个是没有当前元素异常,在获取元素不到元素时抛出,但jdk1.6版本后做了优化,不抛出,返回null
九. 集合框架(LinkedList练习)
1 ) . 需求 : 使用LinkedList模拟一个堆栈或者队列数据结构
1.1 堆栈 --> 特点 : 先进先出 -->如同一个杯子1.2 队列 --> 特点 : 先进先出 --> 如同一个水管
2 ) . Text :import java.util.*;/*自定义封装类*/class duiLie{private LinkedList link;duiLie(){link= new LinkedList();}public void myAdd(Object obj){link.addFirst(obj);}public Object myGet(){return link.removeLast();}public Boolean isNull(){return link.isEmpty();}}class LinkedListText{//主方法public static void main(String args[]){duiLie d =new duiLie();d.myAdd("day01");d.myAdd("day02");d.myAdd("day03");d.myAdd("day04");//获取第一位// sop(d.myGet());//循环遍历while(!d.isNull()){sop(d.myGet());}}//输出方法public static void sop(Object obj){System.out.println(obj);}}
小结 :1. 使用java中集合特有提供的方法来完成自己的封装类2. 通过将已有类封装到自定义封装类的构造方法中,而后实现自有封装类
十. 集合框架(ArrayList ) -->过滤集合中的重复元素
1 ) . 如何过滤掉重复元素?
1.1 创造一个容器,将容器里没有的数据依次往里边放即可
2 ) . ArrayListText :import java.util.*;/*需求: 去掉集合中的重复元素思路: 新创建一个容器,通过判断的方式,一次一次往里边放,然后这个容器里就是不重复的元素了*/class ArrayListText{//过滤重复元素的方法public static ArrayList singleData(ArrayList ary){//新创建的元素容器ArrayList aryNew = new ArrayList();//过滤老容器,放入新容器for(Iterator it=ary.iterator(); it.hasNext();){Object obj = it.next();if(!aryNew.contains(obj))aryNew.add(obj);}//返回新容器return aryNew;}//主方法public static void main(String args[]){//需要被过滤的元素容器ArrayList li = new ArrayList();li.add("Day01");li.add("Day02");li.add("Day01");li.add("Day02");//输出老数据sop(li);//将新容器的数据接收,好输出ArrayList liNew = singleData(li);sop(liNew);}//输出方法public static void sop(Object obj){System.out.println(obj);}}
小结 :1. 通过生活中实际情况编写代码会更高效
十一. 集合框架(ArrayList练习) -->过滤集合中的重复对象
1 ) . 需求 : 将自定义对象作为元素存到ArrayList集合中并去除重复元素2 ) . Text:import java.util.*;/*需求: 将自定义对象作为元素存到ArrayList集合中并去除重复元素思路: 先有对象,再有容器,然后复写equals底层方法,然后传入对象,然后比较即可*/class Person{private String name;private int age;Person(String name,int age){this.name=name;this.age=age;}public String getName(){return name;}public int getAge(){return age;}//这里是直接自动覆盖底层代码public boolean equals(Object obj){//判断实例化的对象是否是Person,因为只有person才做比较if(!(obj instanceof Person))return false;//若是person则向下转型Person p=(Person)obj;//比较对象中名字与年龄是否有重复的地方return this.name.equals(p.name) && this.age==p.age;}}class ArrayListText1{//判public static ArrayList singleData(ArrayList arr){ArrayList arrNew = new ArrayList();for(Iterator it= arr.iterator(); it.hasNext();){Object obj = it.next();if(!arrNew.contains(obj)) //这里的contains底层调用的是equals,因为上边我从新复写了,所以使用的就是复写过的equalsarrNew.add(obj);}return arrNew;}//主方法public static void main(String args[]){ArrayList arr=new ArrayList();arr.add(new Person("sunmmer",12));arr.add(new Person("autumn" ,15));arr.add(new Person("winter" ,18));arr.add(new Person("spring" ,20));arr.add(new Person("sunmmer",12));arr.add(new Person("autumn" ,15));arr.add(new Person("winter" ,18));arr.add(new Person("spring" ,20));//输出原始数据for(Iterator it = arr.iterator();it.hasNext();){Person p = (Person)it.next();sop(p.getName()+"::"+p.getAge());}System.out.println("--------------");//将原始数据过滤ArrayList arrNew = singleData(arr);//输出过滤后的数据for(Iterator it = arrNew.iterator();it.hasNext();){Person p = (Person)it.next();sop(p.getName()+"::"+p.getAge());}}//输出方法public static void sop(Object obj){System.out.println(obj);}}小结 :1. 集合当中判断元素是否相同,依据是元素的equals方法,包括remove / contain 底层都依赖的是 equals
十二. 集合框架(HashSet )
1 ) .Set体系 : 元素是无序的, 元素是不可重复的
1.1 HashSet --> 底层元素结构是哈希表 -->意思就是依照哈希表结构存入,取出的1.2 treeSet -->
2 ) . Demo :import java.util.*;/*set -->元素是无序(存入和取出的顺序不一定一致),元素不可重复-HashSet : 底层元素结构是哈希表-treeSet :set集合的功能和collection是一致的,可查api自己对比*/class HashSetDemo{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){//实例化一个hashset集合HashSet hs1 =new HashSet();//存入的数据hs1.add("Day01");hs1.add("Day02");hs1.add("Day03");hs1.add("Day04");hs1.add("Day04");//取出的数据for(Iterator it= hs1.iterator();it.hasNext();){sop(it.next());}}}
3 ) . 自我总结,可用于随机取数据时使用的嘛
小结 :1. 若在业务中涉及的增删不频繁,则用ArrayList ; 若涉及的增删频繁,则用LinkedList ; 若增删,查都频繁,则建议使用ArrayList2. java命名不可用java中已提供的方法命名,否则jvm编译不通过3. Set中的方法和集合的父接口Collection中的方法是一致的
十三. 集合框架(HashSet存储自定义对象 )
1 ) . HashSet底层是如何保证元素的唯一性呢?
1.1 通过元素的两个方法 --> hashCode 和 equals来完成
[1] 先比较HashCode值是否相同,若不相同则不再判断直接添加,若相同则再通过equals判断,再相同则直接拒绝添加,若不同则添加[2] 小结 : 先判断hashcode(),而后在判断equlas, 两者都不同,才能添加成功,以此保证元素唯一
2 ) . Text : -->保证自定义对象存入HashSet的唯一性import java.util.*;/*set -->元素是无序(存入和取出的顺序不一定一致),元素不可重复-HashSet : 底层元素结构是哈希表-treeSet :set集合的功能和collection是一致的,可查api自己对比*/class Person{private String name;private int age;Person(String name,int age){this.name=name;this.age=age;}public String getName(){return name;}public int getAge(){return age;}//输出方法public static void sop(Object obj){System.out.println(obj);}//复写哈希方法,重置对象返回的哈希地址public int hashCode(){return name.hashCode()+age*39;}//这里是直接自动覆盖底层代码public boolean equals(Object obj){//判断实例化的对象是否是Person,因为只有person才做比较if(!(obj instanceof Person))return false;//若是person则向下转型Person p=(Person)obj;sop("123");//比较对象中名字与年龄是否有重复的地方return this.name.equals(p.name) && this.age==p.age;}}class HashSetText{//输出方法public static void sop(Object obj){System.out.println(obj);}//主方法public static void main(String args[]){//实例化一个hashset集合HashSet hs1 =new HashSet();//存入的数据hs1.add(new Person("summer",12));hs1.add(new Person("autumn",13));hs1.add(new Person("autumn",13));hs1.add(new Person("spring",14));hs1.add(new Person("winter",15));//取出的数据for(Iterator it= hs1.iterator();it.hasNext();){Person p =(Person)it.next();sop(p.getName()+"::"+p.getAge());}}}
小结 :1. 确保元素唯一的两种方式,要么哈希值比较,要么普通值比较
十四. 集合框架(HashSet判断和删除的依据 )
1 ) . HashSet判断和删除的依据是 先依赖 hashCode (),而后再依赖 equals(), 各集合之间的判断方式的不同时因为底层数据结构的不同
十五. 总结
1 ) . ArrayList和HashSet集合都是分别如何保证元素唯一性的?
1.1 ArrayLsit底层中通过复写equals方法来判断确保元素的唯一性-->也就是说他的存储,删除,判断等操作依赖的是equals方法1.2HashSet底层中通过复写hashcode和equals方法来依次判断确保元素的唯一性 -->也就是说他的存储,删除判断等操作依赖的是 先 hashcode() ,而后在 equals 方法1.3 这样看 ,好像 set比 list严谨喔, 判断方式的不同实际上是底层数据结构的不同所导致的
2 ) . List --> 有序,可重复
2.1 ArrayList -->底层数据结构基于数组实现, 有特定索引, 查询快,增删慢2.2 LinkedList --> 底层数据结构基于链表实现, 查询慢,增删快2.3 vector -->底层数据结构也是基于数组实现的,但被arrayList所替代了,唯一一个优点就是线程安全
3 ) . set -->无序的.不可重复
3.1 HashSet -->底层数据结构是基于哈希表实现的,因此判断时比较严谨,先hashcode,再equals3..2 treeSet -->
4 ) . 学完应懂?
4.1 不同的情况使用不同的集合4.2 不同的集合之间不同的特点4.3 不同的集合之间不同的用法4.4 不同的集合之间相同的共性
小结 :1. Colleaction接口总共性 --> Iterator接口迭代器 --> List接口 共性 --> set接口共性 -->List接口细分 -->set接口细分