热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java基础——泛型与集合

第八章泛型与集合第一节泛型定义:泛型是JavaSE1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这

第八章 泛型与集合


第一节 泛型

定义:泛型是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关键字声明类型参数的上界。(在定义类的时候使用,语法表示为: 泛型类) 2.使用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的集合体系

Image

迭代器接口
迭代器(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框架。

推荐阅读
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
author-avatar
瑞风大姑娘_214
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有