第8章 Java泛型与集合类
- 格式:doc
- 大小:166.00 KB
- 文档页数:27
java中集合的概念Java中的集合是一种非常重要的数据结构,用于存储和操作一组对象。
集合框架包含了许多类和接口,可以方便地进行数据的存储、查询、排序等操作,使得Java程序开发变得更加高效和便捷。
在本文中,我们将逐步介绍Java中集合的概念和用法。
一、集合框架概述Java中的集合框架是一个包含了多个接口和类的层次结构,用于表示和操作一组对象。
集合框架包含了通用的集合接口和实现,以及特定的集合类和接口,如List、Set、Map等。
集合框架的接口和类都是通过泛型实现的,可以存储任意类型的对象,比如基本类型和自定义类型的对象。
二、集合框架的接口Java中的集合框架包含了多个接口,其中包括:1. Collection:代表一组对象的集合,是其他集合接口的父接口。
它定义了一些通用的方法,如添加、删除、迭代等。
2. List:代表有序的集合,其中每个元素都有一个对应的索引。
List允许重复元素出现,并且可以通过索引访问、添加、删除元素。
3. Set:代表无序的集合,其中每个元素都是唯一的。
Set不允许重复的元素出现,可以用来去重。
4. Map:代表一组键值对的集合,其中每个键都是唯一的。
Map 允许多个值对应同一个键,可以用来快速查找和存储数据。
三、集合类的实现Java中的集合类可以通过实现集合接口来实现。
如ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等都是集合类的实现,我们可以通过这些集合类来方便地实现对一组对象的操作。
例如:1. 使用ArrayList来实现List接口,可以进行元素的添加、删除、查询等操作:List<String> list = new ArrayList<>();list.add("Alice");list.add("Bob");System.out.println(list.get(1));2. 使用HashSet来实现Set接口,可以去重并存储元素:Set<Integer> set = new HashSet<>();set.add(1);set.add(2);set.add(2);System.out.println(set.size());3. 使用HashMap来实现Map接口,可以快速查找并存储数据:Map<String, Integer> hashMap = new HashMap<>(); hashMap.put("Alice", 12);hashMap.put("Bob", 18);System.out.println(hashMap.get("Bob"));四、集合的迭代Java中的集合类都实现了Iterable接口,因此可以使用迭代器来访问集合中的元素。
java集合的定义1. Java集合是一种用于存储和操作一组对象的数据结构。
它提供了一种更高级别的抽象,可以方便地进行添加、删除、查找和遍历操作。
集合可以存储多个对象,并且可以根据需要动态调整大小。
2. Java集合框架是Java编程语言提供的一组接口、类和算法,用于实现各种集合类型。
它包括了List、Set、Queue和Map等常用集合接口,以及它们的具体实现类。
集合框架提供了一种标准化的方式来处理集合,使得开发人员可以更加方便地使用和操作集合。
3. Java集合框架中的每个集合都是通过特定的接口来定义的。
例如,List接口代表了一个有序的集合,可以包含重复的元素。
Set接口代表了一个无序的集合,不允许包含重复的元素。
Queue接口代表了一个先进先出的队列,可以用于实现任务调度和事件处理等场景。
Map接口代表了一组键值对的映射,可以通过键来查找对应的值。
4. 在集合框架中,每个具体的集合类都实现了相应的接口,并提供了一套通用的方法来操作集合。
例如,ArrayList是List接口的一个实现类,它使用数组来存储元素,并提供了一系列方法来添加、删除、查找和遍历列表中的元素。
HashSet是Set接口的一个实现类,它使用哈希表来存储元素,并提供了一套方法来添加、删除和查找集合中的元素。
5. Java集合框架还提供了一些算法和工具类,可以用于对集合进行排序、查找和操作等操作。
例如,Collections类提供了一系列静态方法,可以对集合进行排序、查找和复制等操作。
Arrays类提供了一系列静态方法,可以对数组进行排序、查找和复制等操作。
这些算法和工具类可以大大简化集合的处理过程,并提高开发效率。
总结:Java集合是一种用于存储和操作一组对象的数据结构,它提供了一种更高级别的抽象,可以方便地进行添加、删除、查找和遍历操作。
Java集合框架是Java编程语言提供的一组接口、类和算法,用于实现各种集合类型,并提供了一种标准化的方式来处理集合。
java泛型语法Java泛型语法是Java编程语言中的一个重要特性,它允许我们编写更加通用和灵活的代码。
通过使用泛型,我们可以在编译时期检测类型错误,并在运行时期避免类型转换异常。
本文将介绍Java泛型的基本语法和使用方法。
一、泛型的定义和作用泛型是Java中的一种参数化类型,它允许我们在定义类、接口和方法时使用类型参数。
通过使用泛型,我们可以将类型作为参数传递给类、接口和方法,从而实现代码的复用和灵活性。
泛型的作用主要有以下几个方面:1. 类型安全:通过使用泛型,我们可以在编译时期检测类型错误,避免类型转换异常。
2. 代码复用:通过定义泛型类、接口和方法,我们可以实现对多种类型的支持,从而提高代码的复用性。
3. 简化代码:通过使用泛型,我们可以减少冗余的类型转换代码,使代码更加简洁。
4. 提高性能:通过使用泛型,我们可以避免使用Object类型,从而减少了装箱和拆箱的开销,提高了代码的执行效率。
二、泛型的基本语法Java中的泛型通过使用尖括号<>来定义类型参数。
在定义类、接口和方法时,我们可以将类型参数放在尖括号中,并在后续的代码中使用该类型参数。
1. 泛型类的定义:```public class GenericClass<T> {private T data;public T getData() {return data;}public void setData(T data) {this.data = data;}}```在上面的代码中,泛型类GenericClass使用了类型参数T。
我们可以在创建GenericClass对象时指定具体的类型,例如:```GenericClass<String> genericString = new GenericClass<>(); genericString.setData("Hello, World!");String data = genericString.getData();```上面的代码中,我们创建了一个GenericClass对象genericString,并指定了类型参数为String。
java泛型详解-绝对是对泛型⽅法讲解最详细的,没有之⼀1. 概述泛型在java中有很重要的地位,在⾯向对象编程及各种设计模式中有⾮常⼴泛的应⽤。
什么是泛型?为什么要使⽤泛型?泛型,即“参数化类型”。
⼀提到参数,最熟悉的就是定义⽅法时有形参,然后调⽤此⽅法时传递实参。
那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于⽅法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使⽤/调⽤时传⼊具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。
也就是说在泛型使⽤过程中,操作的数据类型被指定为⼀个参数,这种参数类型可以⽤在类、接⼝和⽅法中,分别被称为泛型类、泛型接⼝、泛型⽅法。
2. ⼀个栗⼦⼀个被举了⽆数次的例⼦:1 List arrayList = new ArrayList();2 arrayList.add("aaaa");3 arrayList.add(100);45for(int i = 0; i< arrayList.size();i++){6 String item = (String)arrayList.get(i);7 Log.d("泛型测试","item = " + item);8 }毫⽆疑问,程序的运⾏结果会以崩溃结束:1 ng.ClassCastException: ng.Integer cannot be cast to ng.StringArrayList可以存放任意类型,例⼦中添加了⼀个String类型,添加了⼀个Integer类型,再使⽤时都以String的⽅式使⽤,因此程序崩溃了。
为了解决类似这样的问题(在编译阶段就可以解决),泛型应运⽽⽣。
我们将第⼀⾏声明初始化list的代码更改⼀下,编译器会在编译阶段就能够帮我们发现类似这样的问题。
java中八个基本类型的包装类型-概述说明以及解释1.引言1.1 概述概述在Java编程语言中,有八个基本数据类型,即整型(byte、short、int、long)、浮点型(float、double)、字符型(char)和布尔型(boolean)。
尽管这些基本类型在编程中非常有用,但它们并不是对象,因此无法直接进行操作和传递。
为了解决这个问题,Java提供了对应的包装类型,也就是每个基本类型所对应的类。
在Java中,对于每个基本类型都有相应的包装类:Byte、Short、Integer、Long、Float、Double、Character和Boolean。
这些包装类是在Java的标准库中预先定义好的,并提供了许多有用的方法和属性,以便进行更复杂的操作。
在本文中,我们将详细探讨每个基本类型的包装类型,探索它们的作用和优势,以及它们与基本类型之间的关系。
我们还将对Java编程中使用这些包装类型的重要性和应用场景进行讨论。
接下来的章节将深入研究这些方面,并解释为什么在某些情况下使用包装类型是有益的。
我们还将总结基本类型和包装类型的特点,并探讨它们在Java编程中的重要性。
让我们开始这个有趣的探索吧!1.2文章结构1.2 文章结构本篇文章将围绕Java中八个基本类型的包装类型展开讨论。
以下是文章的主要结构:1. 引言:引言部分将提供对Java基本类型和包装类型的简要概述,介绍它们在编程中的作用和使用场景。
2. 正文:2.1 基本类型和包装类型的关系:这一部分将详细探讨基本类型和包装类型之间的关系,包括各种基本类型对应的包装类型的命名规则和特点。
2.2 包装类型的作用和优势:文章将进一步介绍包装类型的作用和优势。
我们将探讨包装类型的主要用途,如提供更多的功能和方法,和基本类型在集合操作中的应用等。
3. 结论:3.1 总结基本类型和包装类型的特点:这一部分将对前文的内容进行总结,重点强调基本类型和包装类型之间的差异和共性,以及使用时需注意的一些问题。
java泛型8泛型的内部原理:类型擦除以及类型擦除带来的问题参考:java核⼼技术⼀、Java泛型的实现⽅法:类型擦除前⾯已经说了,的泛型是伪泛型。
为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉。
正确理解泛型概念的⾸要前提是理解类型擦出(type erasure)。
Java中的泛型基本上都是在编译器这个层次来实现的。
在⽣成的Java字节码中是不包含泛型中的类型信息的。
使⽤泛型的时候加上的类型参数,会在编译器在编译的时候去掉。
这个过程就称为类型擦除。
如在代码中定义的List<object>和List<String>等类型,在编译后都会编程List。
JVM看到的只是List,⽽由泛型附加的类型信息对JVM来说是不可见的。
Java编译器会在编译时尽可能的发现可能出错的地⽅,但是仍然⽆法避免在运⾏时刻出现类型转换异常的情况。
类型擦除也是Java的泛型实现⽅法与C++模版机制实现⽅式之间的重要区别。
可以通过两个简单的例⼦,来证明java泛型的类型擦除。
例1、[java]1. public class Test4 {2. public static void main(String[] args) {3. ArrayList<String> arrayList1=new ArrayList<String>();4. arrayList1.add("abc");5. ArrayList<Integer> arrayList2=new ArrayList<Integer>();6. arrayList2.add(123);7. System.out.println(arrayList1.getClass()==arrayList2.getClass());8. }9. }在这个例⼦中,我们定义了两个ArrayList数组,不过⼀个是ArrayList<String>泛型类型,只能存储字符串。
第8章 Java 泛型与集合类核心内容:1. 集合的作用与概念2. 泛型的作用与用法。
3. Set 、List 、Map 的用法4. Iterator 、Enumeration 的用法8.1 早期的集合类集合可理解为一个容器,该容器主要指映射(map )、集合(set )、列表(list )、散列表(hashtable )等抽象数据结构。
容器可以包含有多个元素,这些元素通常是一些Java 对象。
针对上述抽象数据结构所定义的一些标准编程接口称之为集合框架。
集合框架主要是由一组精心设计的接口、类和隐含在其中的算法所组成,通过它们可以采用集合的方式完成Java 对象的存储、获取、操作以及转换等功能。
集合框架的设计是严格按照面向对象的思想进行设计的,它对上述所提及的抽象数据结构和算法进行了封装。
封装的好处是提供一个易用的、标准的编程接口,使得在实际编程中不需要再定义类似的数据结构,直接引用集合框架中的接口即可,提高了编程的效率和质量。
此外还可以在集合框架的基础上完成如堆栈、队列和多线程安全访问等操作。
在集合框架中有几个基本的集合接口,分别是Collection 接口、List 接口、Set 接口和Map 接口,它们所构成的层次关系如图8-1所示。
图8-1 集合框架层次关系图(1) Collection 接口是一组允许重复的对象。
(2) Set 接口继承Collection ,但不允许集合中出现重复元素。
(3) List 接口继承Collection ,允许集合中有重复,并引入位置索引。
(4)Map 接口与Collection 接口无任何关系,Map 的典型应用是访问按关键字存储的值,所包含的是键—值对,而不是单个独立的元素。
作为对上述接口的实现,Java 语言目前主要提供下述类的定义,如表8-1所示Collection 接口Set 接口 List 接口Map 接口表8-1 集合接口及其类的实现接口集合类的实现历史集合类Set HashSetTreeSetList ArrayList V ectorLinkedList StackMap HashMap HashtableTreeMap由于在JDK1.5当中增加了泛型,我们把JDK1.5之前不支持泛型的集合类称之为早期集合类。
早期的集合有个缺点:当我们把一个对象存放到集合里后,集合就会“忘记”这个对象的数据类型,当再次取出该对象时,该对象的编译类型就变成了Object类型。
早期的集合之所以被设计成这样,是因为设计集合的程序员不知道我们需要用它来保存什么类型的对象。
所以他们把集合设计成能保存任何类型的对象。
但这样做也带来了两个问题:一、集合对元素类型没有任何限制,例如只想创建一个保存String类型的集合,但是程序也允许把boolean类型的对象存放在该集合当中,这样容易引发异常。
二、由于把对象保存在集合当中时,集合忘记了对象的数据类型,只知道它存放的是Object类型,因此取出集合元素后通常要进行强制类型转换。
这种强制类型转换既会增加程序的复杂度,也可能引发ClassCastException。
【例8-1】Test.java 早期集合类1 import java.util.ArrayList;2 import java.util.Iterator;3 import java.util.List;4 public class Test {5 public static void main(String[] args) {6 List list=new ArrayList();7 list.add("beijing");8 list.add("wuhan");9 list.add("shanghai");10 //list.add(4);11 for(int i=0;i<list.size();i++){12 String s=(String)list.get(i);13 System.out.println(s);14 }15 }16 }输出结果:D:\JA V A\8>java Testbeijingwuhanshanghai程序说明:上述程序的第6行是创建一个List集合对象,第7、8、9行是向该集合当中添了一个3个String类型的对象元素,第11、12、13、14行是通过for循环将集合当中的元素取出,转换为String类型并输出。
上述程序只是创建了一个List对象,而且只用List对象来保存字符串对象。
但是对于保存在List对象当中的数据类型我们不能做任何的限制。
如果在程序的第10行,我们不小心把一个int类型的数据保存到List当中,就将导致程序在第12行出现ClassCastException 异常。
自JDK1.5以后,Java引入了泛型的概念,允许我们在创建集合时指定集合元素的类型。
这样添加数据元素到集合中时会做类型检查。
如果要添加的数据元素与指定的数据类型不匹配,编译时会报错。
8.2 泛型在面向对象编程语言中,多态算是一种泛化机制。
例如,你可以将方法的参数类型设为基类,那么该方法就可以接受从这个基类中导出的任何类作为参数。
这样的方法更加通用一些,可应用的地方也多一些。
但有时候,拘泥于类的单继承体系,也会使程序受限太多。
如果方法的参数是一个接口,而不是一个类,这种限制就放松了许多。
因为任何实现了该接口的类都能够满足该方法。
可是有时候,即便使用了接口,对程序的约束也还是太强了。
因为一旦指明了接口,就要求你的代码必须使用特定的接口。
而我们希望达到的目的是编写更通用的代码,要使代码能够应用于“某种不具体的类型”,而不是一个具体的接口或类。
在Java SE 5中增加了泛型机制。
“泛型”这个术语的意思是:“适用于许多的类型”。
泛型实现了参数化类型的概念,使代码可以应用于多种类型。
8.2.1 泛型类一个泛型类就是具有一个或多个类型变量的类。
本节使用一个简单的Pair类作为例子。
public class Pair<T>{private T first;private T second;public Pair(){first=null; second=null;}public Pair(T first,T second){this.first=first; this.second=second;}public T getFirst(){return first;}public T getSecond(){return second;}public void setFirst(T newV alue){first=newV alue;}public void setSecond(T newV alue){second=newV alue;}}Pair类引入了一个类型变量T,用尖括号< >括起来,并放在类名的后面。
泛型类可以有多个类型变量。
例如,可以定义Pair类,其中第一个成员变量和第二个成员变量使用不同的类型:public clas s Pair<T ,U>{…..}类定义中的类型变量指定方法的返回类型以及成员变量和局部变量的类型。
例如:private T first;用具体的类型替换类型变量就可以实例化泛型类型,例如:Pair<String>可以将结果想像成带有构造器的普通类:public class Pair{private String first;private String second;public Pair(){first=null; second=null;}public Pair(String first,String second){this.first=first; this.second=second;}public String getFirst(){return first;}public String getSecond(){return second;}public void setFirst(String newV alue){first=newV alue;}public void setSecond(String newV alue){second=newV alue;}}【例8-2】PairTest.java 泛型类1 public class PairTest{2 public static void main(String[] args){3 Pair<String> pair=new Pair<String>("Hello","Java");4 System.out.println("first="+pair.getFirst());5 System.out.println("second="+pair.getSecond());6 }7 }输出结果:D:\JA V A\8>java PairTestfirst=Hellosecond=Java程序分析:上述程序的第3行创建了一个泛型类对象pair,并指定该对象的成员变量的类型为String 类型。
并调用其带String类型参数的构造方法对其进行初始化。
将pair对象的第一个成员变量first的值设置为"Hello",第二个成员变量second的值设置为"Java"。
第4,5行分别调用pair对象的getFirst()、getSecond()方法获得成员变量first、second的值并输出到控制台。
8.2.2 泛型方法前面已经介绍了如何定义一个泛型类。
实际上,还可以定义一个带有参数类型的方法即泛型方法。
泛型方法使得该方法能够独立于类而产生变化,泛型方法所在的类可以是泛型类,也可以不是泛型类。
创建一个泛型方法常用的形式如下:[访问修饰符] [static] [final] <参数类型列表> 返回值方法名( [形式参数列表] )下面我们在GenericMethod类当中声明一个f ( )泛型方法,用于返回调用该方法时,所传入的参数类型的类名。
【例8-3】GnericMethodTest.java 泛型方法1 class GenericMethod{2 public <T> void f(T x){3 System.out.println(x.getClass().getName());4 }5 }67 public class GenericMethodTest{8 public static void main(String[] args){9 GenericMethod gm=new GenericMethod();10 gm.f(" ");11 gm.f(1);12 gm.f(1.0f);13 gm.f('c');14 gm.f(gm);15 }16 }输出结果:D:\JA V A\8>java GenericMethodTestng.Stringng.Integerng.Floatng.CharacterGenericMethod程序分析:上述程序的第9行创建了一个GenericMethod类型的对象gm。