作者:瑞风大姑娘_214 | 来源:互联网 | 2023-09-25 21:12
第八章 泛型与集合 第一节 泛型 定义:泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。泛型可以自动进行数据类型的转换。
为什么要用泛型?
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
特点:是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率,让程序变得更加严谨,安全简单。
例子一:使用了泛型class Gen {private T fb; //定义泛型成员变量public Gen(T fb) {this.fb = fb;}public T getFb() {return fb;}public void setFb(T fb) {this.fb = fb;}public void showType() {System.out.println("T的实际类型是: " + fb.getClass().getName());} }public class GenDemo {public static void main(String[] args){String a=“helloworld”; Gen str=new Gen(a);str.showTyep(); String s = str.getFb(); } }
例子 一,最后运行不会报错,使用了泛型自动进行了数据的转换
例子二:没有使用泛型public class Gen2 {private Object sb; //定义一个通用类型成员public Gen2(Object sb) {this.sb = sb;}public Object getSb() {return sb;}public void setSb(Object sb) {this.sb = sb;}public void showTyep() {System.out.println("T的实际类型是: " + sb.getClass().getName());} }public class GenDemo2 {public static void main(String[] args) {String a=“helloworld”; Gen2 str=new Gen2(a);str.showTyep(); double s = (double) str.getSb(); }}
例子 二,最后运行会出现报错,因为String类型的字符内容不能强制转换成double类型
第二节通配符 通配符:使用一个奇怪的问号(?)表示类型参数 , 是一种表示未知类型的类型约束的方法。通配符并不包含在最初的泛型设计中(起源于 Generic Java(GJ)项目),从形成 JSR 14 到发布其最终版本之间的五年多时间内完成设计过程并被添加到了泛型中。
个人对通配符的简单理解和运用 :
public class Test{public static void mytype(Generic> g){ //→这里的?表示泛型里面不确定的任意类型,如果?变成Object,1不会报错;2,3会出现类型错误;** //如果?变成Integer,1和3会报错,2不会报错g.showDataType();}public static void main(String[] args){Generic g=new Generic("helloworld"); //1 Generic g=new Generic(10); //2Generic g=new Generic(0.5); //3} }
有界类型 有界类型是对泛型的参数类型的取值范围进行一定程度的限制,有界类型分为两种:
1.使用extends关键字声明类型参数的上界。(在定义类的时候使用,语法表示为: 泛型类 extends 父类>) 2.使用super关键字声明类型参数的下界。(使用的时候进行定义,语法表示为: 泛型类 super 子类>)
※来源:http://blog.csdn.NET/flfna/article/details/6576394 通用对有界类型的解释
在本文的前面的部分里已经说过了泛型类型的子类型的不相关性。但有些时候,我们希望能够像使用普通类型那样使用泛型类型:
◆向上造型一个泛型对象的引用 ◆向下造型一个泛型对象的引用
向上造型一个泛型对象的引用
例如,假设我们有很多箱子,每个箱子里都装有不同的水果,我们需要找到一种方法能够通用的处理任何一箱水果。更通俗的说法,A 是B 的子类型,我们需要找到一种方法能够将C 类型的实例赋给一个C类型的声明。 为了完成这种操作,我们需要使用带有通配符的扩展声明,就像下面的例子里那样:
List apples = new ArrayList(); List
第三节 集合概述 Java的集合
Java的集合石一些常用的数据结构,示例:队列、栈、链表等。Java集合更像是一种“容器”。
集合框架 JDK5.0之前的版本,Java集合会丢失容器里的所有对象的数据类型,并且数据类型被当成Object类型进行处理;JDK5.0之后增加了泛型,Java集合完全支持泛型,可以记住容器里的数据类型, 从而可以编写更加简洁,健壮的代码。
Java所有的集合类都在Java.util包下,从JDK5.0开始为了处理多线程环境下的并发安全问题,又在Java.util.concurrent包下提供了一些多线程支持的集合类。
Java的集合类主要由两个接口派生而出:Collection和Map,这两个接口派生出一些子接口和实现类。
Java的集合分为三大类:
1.Set集合 (无法记住每次添加的元素顺序,集合中元素不能重复) 2.List集合(会记住每次添加的元素顺序,集合中的元素可重复且长度可变) 3.Map集合(每个元素都有key/value键值对组成,可以根据元素的key来访问此元素的value,Map集合的key不允许重复,value可重复)
Collection接口 Collection接口是Set,Queue和List接口的父接口,该接口中定义的方法可以操作者三个接口中的任意一个集合,Collection接口中常用的方法如下表所示:
注意: 使用Collection接口中的一些方法如:add(),addAll(),remove()removeAll(),retainAll()时会出现UnsupportedOperationException异常;把一个不兼容的对象添加进集合中时,会产生ClassCastException异常;虽然collection可以储存任何Object对象,但不建议在同一个集合容器中储存不同类型的对象,建议使用泛型增强集合的安全性,以免引起ClassCastException异常。
Collection的集合体系
迭代器接口 迭代器(Iterator)可以采用统一的方式对Collection集合中的元素进行遍历操作,开发人员不需要关心Collection集合中的内容,也不必实现IEnumerable或者ienumerator接口就能够使用foreach循环遍历集合中的部分或者全部元素。
Java从5.0开始增加了Iterable新接口,该接口是Collection接口的父接口,因此所有实现了Iterable()方法可以获得每个集合自身的迭代器Ierator。Iterator是集合的迭代器接口,定义了常见的迭代方法,用于访问,和操作集合中的元素。
List接口 (是Collection接口的子接口,可以使用Collection接口中的全部方法,默认按照元素添加顺序设置元素的索引,ArrayList和Vector是List接口的两个典型实现类) Set接口 (常用的实现类包括HashSet,TreeSet和EnumSet) Queue接口 (队列Queue,通常以先进先出(FIFO)方式排序各个元素) Map接口 (是集合框架的另一个根接口和Conllection接口并列,两个常用的实现类是:HashMap(key/value可以为空),TreeMap(key/value不允许为空))
第四节集合转换 Java集合框架有两大体系:Collection和Map;两者虽然本质上是不同的,各自具有自身的特性,但是可以将Map集合转换为Collection集合。
Map集合转换Collection集合的三个方法:
entrySet(): 返回一个包含了Map中元素的集合,每个元素都包括键和值。 keySet():返回Map中所有键的集合。 values():返回Map中所有值的集合。
示例:
public class HashMapDemo{public static void main(String[] ars){HashMap hm=new HashMap();hm.put("a","第一条信息"):hm.put("b","第二条信息"):hm.put("c","第三条信息"):hm.put("d","第四条信息"):hm.put("e","第五条信息"):Set> entryset=hm.entrySet();for(Entry entry:entryset){System.out.println("键:"+entry.getKey()+"值:"+entry.getValue());} } }
集合工具类 Java集合框架中提供了两个非常实用的辅助工具类:Collections和Arrays。
※Collections工具类提供了一些对Collectio集合常用的静态方法,例如:排序、复制、查找、以及填充等操作。
※Arrays工具类则提供了针对数组的各种静态方法,例如:排序、复制、查找等操作。
要点: Collection和Collections的区别:
1.java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。 2.java.util.Collections 是一个包装类(工具类/帮助类)。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架。