41.黑马程序员-集合框架、泛型
来源:互联网 发布:淘宝账号出售 编辑:程序博客网 时间:2024/06/02 05:30
------- android培训、java培训、期待与您交流! ----------
一、集合框架概述 1.体系概述
- 为什么出现集合类?
- 面向对象语言对事物的体现都是以对象的形式,对象多了,出现了存储对象的集合。
- 数据多了,需要进行封装成对象。有两种存储方法:数组和集合。
- 有数组为什么出现集合?
- 对象多了用集合存储,数据多了用对象存。
- 数组是固定长度的,集合是可变长度的。
- 数组只能存同一种数据,集合中只要是任意对象就可以。
2集合的特点
- 集合作为容器可以分为很多种,如水杯就有很多种。
- 多种集合的共性抽取,就是集合框架:Collection。 抽取的不一定能创建对象,所以需要参阅顶层创建子类对象。
- 集合中元素取出方式:迭代器、遍历、for循环、按角标索引 、枚举
3.集合框架
- Collection
- |--List //元素是有序的,元素可以重复,因为该集合有序。
- |--ArrayList
- |--LinkedList
- |--Vector
- |--Set//元素是无序的,
- |--HashSet
- |--TreeSet
- |--List //元素是有序的,元素可以重复,因为该集合有序。
- 为什么出现这么多的容器?
- 因为每一种容器的存储方式都不同,这个存储方式称之为数据结构。
- 集合共性方法:
- 1.add方法: add方法的参数类型是Object,以便于接受任意类型对象。
- 2.集合中存储的都是对象中的引用(地址)。
- 栈里存放集合和数据对象的引用,堆中存放集合对象(包含数据对象的引用)、数据对象。
- 3.删除元素。
- remove("java02");//删除java02这个元素。
- clear(); //清空
- 4.判断元素
- al.contains("java02");//java02是否存在。
- al.isEmpty();//al是否为空。
- 5.取交集retainAll
- al1.tetainAll(al2);//取交集,没交集为空。
二、迭代器
1.概念
- 迭代器就是集合的取出元素的方式。
- 迭代器 Iterator是一个接口。
- 接口型引用只能指向自己的子类对象。
- 接口引用指向了子类对象,意思就是接口的引用能够指向实现它的类的一个对象,然后通过这个接口的引用,来调用接口的属性和方法(调用的其实是实现了他的类的方法)。
- 取出方式、Iterator接口、内部类
- 取出比较复杂,不足以用一个方法描述,需要多个功能,将取出动作封装成一个对象。
- 取出对象描述成一个类,因为只操作集合中的元素定义在内部比较方便,所以此类为内部类。完成取出动作的定义。
- 因为各种集合数据结构不同,各有自己的取出对象。但是都有共性内容:判断、取出。共性可以抽取为Iterator接口。
- 定义Iterator iterator ();
- 使用方法一:
- 第一步:ArrayList al = new ArrayList();
- 第二步:Iterator it = al.itarator();//
- itarator对象是通过集合的方法获取出来的,不是new出的,
- 然后接口型引用it指向了al.itarator这个对象,这样可以调用al.itarator的方法。
- 迭代器可以获取集合中的元素。获取方法:
- 第三步:while(it.hasNext())//这里 it.hasNext()当有元素返回true。
- {
- sop(it.next());//每次输出下一个元素。
- }
- {
- 使用方法二
- for(Iterator it = al.iterator(); it.hasNext; )//好处是it用完释放,节省内存。
- {
- sop(it.next());
- }
三、List集合
- ListIterator :
- ListIterator概念
- Iterator当添加完元素并且建立完迭代器后, 因为迭代器只知道前面的元素 ,不要再使用集合方法添加、删除元素,会引发并发修改异常。
- Iterator迭代器有局限性,只能删除,不能添加。为了解决Iterator局限性,可以使用它的子接口ListIterator。
- 因为 ListIterator迭代器有指针、角标,所以方法比Iterator多的多,可以添加、判断、删除、取出、修改等。
- 只有List集合有在遍历过程中增删改查的方法,因为它有角标。
- ListIterator使用方法
- 增删改查。
- boolean hasPrevious():
- 如果以逆向遍历列表,列表迭代器有多个元素,则返回true。
- 意思与hasNext判断后面有没有相反,是判断前面有没有。
- ListIterator概念
- ArrayList
- ArrayList概念
- 底层的数据结构使用的是数组结构。
- 线程不同步。
- 可变长度数组:默认长度为10的空列表。超过则延长50%。将原来数组copy到新数组来,再把新元素添加到新数组中。
- 数组结构是每个元素都有编号。
- 特点是查找很快、修改很快。 增删需要移位 ,增加、删除较慢。元素越多越明显。
- ArrayList概念
- LinkedList
- LinkedList概念
- 底层使用的链表数据结构。
- 线程不同步。
- 链表是后面一个元素记住前一个链表。
- 特点是增删速度很快、查询、稍慢、修改需要依次往下问,增删的时候只需要这个元素记住前后元素就可以。
- LinkedList概念
- Vector
- Vector概念
- 底层是数组数据结构,JDK1.0出现。 被ArrayList替代。
- Vector是同步的。
- 可变长度数组:默认长度为10的空列表。超过则延长100%。
- Vector
- 枚举是Vector的特有取出方式。需要枚举时使用Vector。
- 迭代器与枚举的区别:迭代器是枚举的功能加强,迭代器添加了一个可选的移除操作,并使用较短的方法名。优先使用迭代器。
- Vector概念
四、Set集合
- |--Set
- |--HashSet
- 数据结构是哈希表,线程是非同步的。
- 保证元素唯一性的原理:hashCode值是否相同。如果相同,判断equals方法。
- |--TreeSet:不常见。
- 可以对Set集合中的元素进行排序。
- 底层数据结构是二叉树。
- 保证元素唯一性的原理:compareTo方法return 0.
- TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Compareble接口,实现compareTo方法。这种默认排序方式被称为自然顺序
- TreeSet排序的第二种方式:
- 当元素不具备比较性,或者比较性不是所需要的,这时就需要让集合具备比较性。
- 集合相当于刻度板,两个元素在刻度板下一站就能比较出来。
- 定义一个类实现Comparetor接口,覆盖compare方法。 在集合初始化时,就有了这种比较方式,把这个类作为参数传给TreeSet的构造方法。
- 保证唯一性:return 0判断唯一性。
- Set :元素是无序的(存入和取出顺序不一定一致),并且元素不可以重复。
- Set<E>是一个接口。
- Set集合的功能和collection功能是一致的。
- |--HashSet
- HashSet集合
- 底层结构是Hash表
- Hash表:
- 存放一堆Hash值,存的顺序是按照Hash值,取得时候顺序不一定一致,
- 如果Hash值重复的时候,equals判断元素是否是一个对象,不是一个对象会在另一个对象下顺延
- HashSet方法类似于Collection,取出元素用Iteratoe迭代器。
- HashSet的对象比较需要判断:重写了的hashCode()和equals(), hashCode()判断相同时,再判断equals().为了效率,hashCode()中就直接判断对象是否相同,不同直接return 负数。相同再equals()。
- 想要HashSet中的元素对象唯一,需要对象 equals挨个判断是否相同(默认equals判断地址,需要复写)。但是前提是HashCode相同才会判断equals,所以首先复写HashCode,然后复写equals。*39
- 二叉树-个人理解:
- 二叉树存储:
- 第一个值定位初始值,以后的值与这个初始值比较,分成两个叉:左小右大,依次一层层向下排。
- 值多了以后,初始值就不一定是中间值效率就低了,这时二叉树会自动取折中值。
- 二叉树取出:
- 从小打到取,从左叉的左下角最小值开始依次取到顶
- 再到右叉取,从右叉的左下角最小值开始依次取,每一次取到上一层再取上一层的右小叉,一直到结束。
- 二叉树的小技巧
- Set中,元素一般是无序的,但是TreeSet中使用一个小技巧可以实现怎么存的怎么取出:compareTo()方法返回正数即可。当然也可以返回负数取反,返回0只取第一个。
- 二叉树存储:
五、Map接口
1.概述
接口Map<K,V>
K:key。V:value。
作用:将键映射到值的对象,一个键只能映射一个值,键是唯一的。
区别:双列集合。
2.功能
添加:注意,如果添加相同键,后值覆盖前值,并put方法返回被覆盖的值
删除
判断
获取
3.Map扩展
Map集合被使用是因为具备映射关系。
Map是键-值对形式,一般是两个元素映射,如果有三个元素呢?
解决方法是一个键对应一个值(键值对),实现一对多的关系。
格式如下 HashMap <键的类型, HashMap <键的类型 ,值得类型>> 引用变量= new HashMap <键的类型, HashMap <键的类型 ,值得类型>>();
举例:HashMap<String,HashMap<String,String>> hm = new HashMap<String,HashMap<String,String>>( );
put();
map.put(01,"zhangsang");// 第一次存 ,这一句的返回值是null,
map.put(01,"lisi");//这一句的返回值是zhangsan。
为什么会这样,put()返回的是这个键原来的值,形象点就是,压入一个值把原来的值挤出来了^^。
4.KeySet
map集合的两种取出方式:1,返回set<k>keySet():将map中所有的键存入到Set集合。因为set具备迭代器。所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。举例:2,返回set<Map.Entry<K,V>>entrySet():将map集合中的映射关系取出,存入到Set集合中。5.Map中需要注意的:举例:
当一个map存放多个对象时,就需要让对象具备比较性,有备无患。
创建的对象中也需要注意:
1,为了比较对象,覆盖hashCode()和equals()。覆盖hashCode的原因是jvm调用equals前会先调用hashCode()。2,再就是需要implements实现comparator接口,覆盖compareTo()以便比较.
六、泛型
- 泛型是JDK1.5以后的新特性,用于解决安全问题,是一个安全机制。
- 好处:
- 1,将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题,让运行时期问题减少,安全增加。
- 2,避免了强制转换的麻烦。
- 格式:通过<>来定义要操作的引用数据类型。
- 用途:什么时候使用泛型。
- 通常在集合框架中很常见,只要见到<>就要定义泛型,例如接口Collection<E>,ArrayList<E>.
- 其实<>就是接受类型的,当使用集合时,将集合中要存储的数据类型作为参数放到<>中即可。
- 重点:泛型类、泛型方法。
七、泛型类
- 什么是泛型类,就是带泛型的类。
- 定义位置:
- 类名后面: class Utils<泛型>,Demo <泛型> d = new Demo<泛型>();
- 方法返回值前面:public <T> T findById(int id)
- class 类型 <泛型>
- 什么时候定义泛型类?
- 当类中要操作的引用数据类型(基本数据类型不行)不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成扩展。
- 举例
//泛型类,就是带泛型的类--!class Utils<QQ>{private QQ q;public void setObject(QQ q){this.q = q;}public QQ getObject(){return q;}}
- 使用泛型类
Utils<Worker> u = new Utils<Worker>(); //new 一个泛型类对象。
u.setObject(new Worker()); //new一个对象作为参数传入。
Worker w = (Worker) u.getObject(); //获取对象。注意这里Object转为Worker
u.setObject(new Worker()); //new一个对象作为参数传入。
Worker w = (Worker) u.getObject(); //获取对象。注意这里Object转为Worker
八、泛型方法
- 把泛型定义在方法上,就是泛型方法。
- 泛型定义位置:返回值前面
- public static <W> void method(W w)
- 作用:
- 泛型定义在类上,会对整个类有效,泛型类中的方法类型也就确定了。
- 为了让不同方法可以操作不同类型,而且类型还不确定。
- 举例:
class Demo{public<T> void show(T t){System.out.println("show:"+t);}public <Q>void print(Q q){System.out.println("print:"+t);}}
- 这时候可以多个相同或不同方法可以使用不同的泛型。
- d.show("haha");
- d.show(new Integer(4));
- d.print("haha");
- d.print(new Integer(4));
- 这个泛型仅仅作用于这个方法,传什么操作说明,新方法用另外的泛型。
- 泛型类和泛型方法可以同时使用
class Demo <T>{public <T>void show(T t){System.out.println("show:"+t);}public <Q>void print(Q q){System.out.println("print:"+t);}}
九、静态方法泛型
- 静态方法不可以访问类上定义的泛型,原因是静态方法存在的时候对象还不存在。
- 可以将泛型定义在静态方法上。
class Demo <T>{public static <M> void method(M m){System.out.println("method:"+m);}}
- 泛型定义在接口上。
interface Inter<T>{void show(T t);}class InterImpl <T> implements Inter<T>{public void show(T t){System.out.println("show:"+t);}}
- 泛型定义在参数上,如
- public static void printColl(ArrayList<String> al ){}
- 可以写成这样
- public static void printColl(ArrayList<?> al ){}
- 好处是?限定符可以是任意类型。
public static void printColl(ArrayList<?> al1 ){Iterator <?> it = al.iterator();while (it.hasNext()){System.out.println(it.next());}}
- ?与T的区别,?代表不确定的类型后面不可用,T在后面可以作为确定的类型使用,比如T T = it.next();。
- 那么?不如T的话,好处是什么?
- 子类继承了父类,而在子类存入父类类型集合中,却不可以。
- ?可以限定传入的参数类型。
- public static void printColl(ArrayList<? extends Person> al1 )。只能传入Person及其子类。迭代器中泛型也要 <? extends Person>
- 41.黑马程序员-集合框架、泛型
- 黑马程序员---集合框架<泛型>
- 黑马程序员----集合框架、泛型
- 黑马程序员:集合框架
- 黑马程序员-集合框架
- 黑马程序员-集合框架
- 黑马程序员:集合框架
- 黑马程序员-----集合框架
- 黑马程序员: 集合框架
- 黑马程序员-集合框架
- 黑马程序员--集合框架
- 黑马程序员- 集合框架
- 黑马程序员-集合框架
- 黑马程序员--------集合框架
- 黑马程序员----集合框架
- 黑马程序员 集合框架
- 黑马程序员 集合框架
- 黑马程序员:集合框架
- 黑马程序员________Java高新技术之反射机制及枚举注释
- ubuntu12.04 常用命令
- JavaScript解析XML的方法总结
- 母版页、用户控件和页面
- 生产者消费者问题
- 41.黑马程序员-集合框架、泛型
- 解析xml文件的标签内容
- Eclipse.ini 优化设置
- 42.黑马程序员-常用容器
- 我的WCF之旅(1):创建一个简单的WCF程序
- 禁用ViewState
- 程序员从初级到中级10个秘诀
- 学会用core dump调试程序错误(转)
- JS弹窗