11 使用泛型和集合框架_Java
- 格式:doc
- 大小:335.00 KB
- 文档页数:46
java 泛型的三种定义与使用方法Java中的泛型主要有三种定义方式,分别是:类型参数、类型参数化类和类型参数化方法。
下面是它们的定义和使用方法:1. 类型参数:类型参数是泛型的主要形式,它允许我们在定义类、接口或方法时指定一个或多个类型参数。
这些类型参数在类、接口或方法的实现中被用作类型占位符,以便在运行时确定实际类型。
定义类型参数的方法是在类、接口或方法的名称后面加上尖括号<>,并在其中指定一个或多个类型参数。
例如:```javapublic class Box<T> {private T content;public Box(T content) {= content;}public T getContent() {return content;}}```在上面的例子中,我们定义了一个名为Box的泛型类,它有一个类型参数T。
我们可以使用任何类型来实例化Box对象,例如Box<Integer>、Box<String>等。
2. 类型参数化类:类型参数化类是将一个类作为泛型参数。
这种定义方式主要用于集合框架中的类,例如List、Set、Map等。
定义类型参数化类的方法是在类名后面加上尖括号<>,并在其中指定一个或多个类型参数。
例如:```javaList<String> list = new ArrayList<>();Set<Integer> set = new HashSet<>();Map<String, Integer> map = new HashMap<>();在上面的例子中,我们定义了三个类型参数化类:List、Set和Map,并使用它们创建了三个不同类型的对象。
这些对象在运行时会自动处理实际类型的匹配。
3. 类型参数化方法:类型参数化方法是在方法中使用泛型。
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入门●第二章数据类型和运算符●第三章流程控制与数组●第四章封装●第五章继承●第六章抽象类与接口●第七章多态●第八章异常●第九章多线程机制●第十章输入输出流●第十一章使用泛型和集合框架●第十二章基于Swing的图形用户界面(GUI)设计●第十三章Java事件驱动编程第一章练习题(Java入门)1.下列哪项不是JDK所包含的内容?(选一项)A.Java编程语言B.工具及工具的APIC.Java EE扩展APID.Java平台虚拟机2.下列关于JDK、JRE和JVM的描述。
哪项正确?A.JDK中包含了JRE,JVM中包含了JREB.JRE中包含了JDK,JDK中包含了JVMC.JRE中包含了JDK,JVM中包含了JRED.JDK中包含了JRE,JRE中包含了JVM3.下列哪个工具可以编译java源文件?A.javacB.jdbC.javadocD.junit4.JDK工具javadoc的作用是哪项?A.生成Java文档B.编译Java源文件C.执行Java类文件D.测试Java代码5.以下哪些包是Java标准库中常用的包?(选三项)A.java.langB.javax.servlet .httpC.j ava. ioD.java.sql6.使用JDK工具生成的Java文档的文件格式是?A.XML格式B.自定义格式c.二进制格式D.HTML格式7.以下关于JVM的叙述,哪项正确?(选两项)A.JVM运行于操作系统之上,它依赖于操作系统B.JVM运行于操作系统之上,它与操作系统无关C.JVM支持Java程序运行,它能够直接运行Java字节码文件D.JVM支持Java程序运行,它能够直接运行Java源代码文件8.以下关于支持Java运行平台的叙述,哪项错误?A.Java可在Solaris平台上运行B.Java可在Windows平台上运行C.Java语言与平台无关。
Java程序的运行结果依赖于操作系统D.Java语言与平台无关。
java中泛型的作用泛型是Java语言的一项强大特性,它允许我们在定义类、接口、方法等时使用类型参数,从而使得代码更加灵活和可复用。
泛型的作用主要体现在以下几个方面:1.类型安全:泛型提供了一种编译时的类型检查机制,可以在编译阶段捕获一些类型错误。
通过使用泛型,我们可以在编译时检查参数类型是否匹配,避免了在运行时可能产生的类型转换异常。
2.代码复用:使用泛型可以编写更加通用的代码,提高代码的可复用性。
通过定义泛型类或泛型方法,我们可以将相似代码逻辑抽象出来,以适用于不同的类型,从而减少重复编写代码的工作量。
3. 集合类的类型安全:泛型集合类(如ArrayList、HashSet等)可以指定存储的元素类型,使得集合中的元素都是指定类型。
这样可以在编译时就避免了将错误类型的对象存入集合的问题,并且在读取集合中的元素时可以直接获取到正确类型的对象,避免了类型转换的繁琐与风险。
4. 简化代码:在没有泛型之前,我们可能需要编写各种类型的容器类,如IntList、StringList等,用于存储不同类型的元素。
而有了泛型,我们可以使用通用的容器类List,通过指定泛型参数的方式来存储不同类型的元素,从而大大简化了代码结构。
5.提高性能:使用泛型可以避免一些不必要的类型转换,从而提高程序的执行效率。
在编译时确定了泛型类型后,编译器会自动插入类型转换的代码,避免了动态类型检查所带来的性能损失。
6.编写更安全的API:通过使用泛型,我们可以将一些类型相关的约定和规范编码到API中,从而可以在编译时强制执行这些约定,提高代码的安全性和可靠性。
7.代码逻辑清晰:泛型可以使代码更具可读性和可维护性。
通过使用泛型,我们可以在编程时直观地表达出代码逻辑的意图,从而使代码更加清晰明了。
总之,泛型是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 list泛型的用法Java是一种面向对象的编程语言,提供了丰富的类和接口用于开发各种类型的应用程序。
其中,List是一种非常常用的集合类,用于存储一组元素。
在Java中,可以使用泛型来定义List的类型,使其能够存储不同类型的对象。
本文将介绍Java List泛型的用法。
一、泛型的概念泛型是一种在Java中引入的概念,用于增强类型安全性。
通过使用泛型,可以在编译期间检测出类型不匹配的错误,避免在运行时抛出类型转换异常。
二、使用泛型的好处1. 提高类型安全性:使用泛型可以确保集合中只存储指定类型的对象。
2. 代码重用性:使用泛型可以编写通用的代码,使得代码可以适用于不同类型的数据。
三、List泛型的基本用法在Java中,可以使用以下语法声明一个具有泛型的List:List<T>,其中T是一个类型参数。
通过指定具体的类型参数,可以将List限定为存储特定类型的对象。
示例代码如下:```javaList<String> stringList = new ArrayList<>(); // 声明一个存储String 类型对象的ListList<Integer> integerList = new ArrayList<>(); // 声明一个存储Integer类型对象的List```通过使用泛型,List将只能存储指定类型的对象。
如果尝试将不兼容的对象添加到List中,将在编译期间报错。
四、使用泛型限定类型除了可以使用具体的类型作为泛型参数外,还可以使用通配符来限定使用的类型范围。
在Java中,可以使用 "?" 来表示通配符。
以下是使用通配符的示例:```javaList<?> list = new ArrayList<>(); // 声明一个可以存储任意类型对象的ListList<? extends Number> numberList = new ArrayList<>(); // 声明一个可以存储Number类型及其子类对象的ListList<? super Integer> integerList = new ArrayList<>(); // 声明一个可以存储Integer类型及其父类对象的List```通过使用通配符,可以实现更灵活的类型限定,使得List能够存储更多种类的对象。
Java程序设计中的泛型编程应用案例泛型编程是Java中一种强大的特性,它可以提供更加灵活和安全的代码复用,同时也可以增加程序的可读性和可维护性。
在本文中,我们将探讨几个Java程序设计中的泛型编程应用案例。
1. 集合框架中的泛型Java的集合框架提供了丰富的数据结构,如ArrayList、HashSet等。
这些集合类的实现中广泛使用泛型来实现类型安全。
例如,在ArrayList中可以定义一个ArrayList<String>,这样就限制了该集合只能存储字符串类型的对象。
这样可以在编译阶段进行类型检查,避免在运行时出现类型转换错误。
2. 自定义泛型类除了使用Java的内置泛型类,我们还可以自定义泛型类来应用于特定的需求。
例如,假设我们需要实现一个泛型的栈(Stack)数据结构,我们可以使用如下的方式定义泛型类:```javapublic class Stack<T> {private ArrayList<T> stackList;public Stack() {stackList = new ArrayList<T>();}public void push(T element) {stackList.add(element);}public T pop() {return stackList.remove(stackList.size() - 1);}}```在上述代码中,我们使用`<T>`来定义泛型类型,并在类中使用泛型类型`T`作为数据成员的类型。
3. 泛型方法除了泛型类,Java还提供了泛型方法的支持。
泛型方法可以在方法中独立地使用泛型类型,并且不一定要与类中定义的泛型类型相同。
下面是一个使用泛型方法的例子:```javapublic class MathUtils {public static <T extends Comparable<T>> T findMax(T[] array) { T max = array[0];for (int i = 1; i < array.length; i++) {if (array[i].compareTo(max) > 0) {max = array[i];}}return max;}}```在上述代码中,`findMax`方法使用了泛型类型`T extends Comparable<T>`,它要求传入的数组类型需要实现`Comparable`接口,从而可以进行比较操作。
java feature的用法Java Feature 的用法在 Java 编程语言中,有很多特性可以帮助我们更加有效地开发应用程序。
下面列举了一些常见的 Java 特性,并对每个特性进行详细讲解。
1. 泛型(Generics)泛型是 Java 5 引入的特性,它允许我们在编译时检查对象的类型安全性。
通过使用泛型,可以在编译时捕获类型错误,减少运行时错误的发生。
例如,我们可以定义一个类型安全的集合类,只允许存储特定类型的对象。
2. Lambda 表达式Lambda 表达式是 Java 8 引入的特性,它使得我们可以更加简洁地编写函数式代码。
Lambda 表达式允许我们直接以内联的方式定义匿名函数,使得代码更加易读和简洁。
通过使用 Lambda 表达式,我们可以在集合操作、线程处理等场景中提高代码的可读性和可维护性。
3. Stream APIStream API 是 Java 8 引入的特性,它提供了一种处理集合数据的更加便捷和高效的方式。
Stream API 可以通过链式调用一系列的操作来处理集合数据,如过滤、映射、排序等,从而减少了繁琐的集合操作代码。
使用 Stream API,我们可以更加简洁和可读地处理大量的数据。
4. 多线程编程Java 提供了多线程编程的支持,使得我们可以并发地执行代码,提高程序的性能和响应能力。
通过使用多线程,我们可以将任务分解为多个子任务并行地执行,从而加快程序的运行速度。
Java 的多线程编程提供了线程的创建、同步、通信等功能,使得我们可以更加灵活地控制程序的执行流程。
5. 反射(Reflection)反射是 Java 提供的一种机制,允许程序在运行时动态地获取和操作类的信息。
通过使用反射,我们可以在运行时获取类的字段、方法、构造函数等信息,并通过反射调用这些信息。
反射为我们提供了一种强大的机制,可以实现很多动态和灵活的功能,如动态代理、依赖注入等。
6. 注解(Annotation)注解是一种在代码中添加元数据的方式,它可以提供给编译器、虚拟机或其他工具使用。
java 泛型用法实例Java 泛型是一种将类型参数化的方法,通过它可以在编译时检测到类型不匹配的错误。
泛型的核心思想是参数化类型,实现了代码的重用性和类型的安全性。
下面我将通过一些实例来介绍 Java 泛型的用法。
1. 泛型类泛型类是指在定义类时使用类型参数来代替真实类型。
例如,我们可以定义如下的一个泛型类来表示一个有序对(Ordered Pair):```public class OrderedPair<K, V> {private K key;private V value;public OrderedPair(K key, V value) {this.key = key;this.value = value;}public K getKey() {return key;}public V getValue() {return value;}}```在上面的例子中,`K` 和 `V` 是类型参数,用来代替真实的类型。
在使用该类时,我们可以指定实际的类型来创建对象:```OrderedPair<Integer, String> p1 = new OrderedPair<Integer, String>(1, "One");OrderedPair<String, Integer> p2 = new OrderedPair<String, Integer>("Two", 2);```2. 泛型方法泛型方法是指在定义方法时使用类型参数来代替方法中的参数类型。
例如,我们可以定义如下的一个泛型方法来交换数组中的两个元素:```public static <T> void swap(T[] array, int i, int j) {T temp = array[i];array[i] = array[j];array[j] = temp;}```在上面的例子中,`<T>` 表示该方法是一个泛型方法,类型参数 `T` 用来代替真实的类型。
第11章使用泛型和集合框架目标当完成本章后,你应该能够:•了解集合•了解并使用List接口•了解并使用Set接口•了解并使用Map接口•了解遗留的集合类•通过实现Comparable 和Comparator 接口创建自然排序和自定义排序•使用泛型集合•了解泛型类中类型参数的使用•重构已存在的非泛型代码•编写对集合进行迭代的程序•了解增强型for 循环Collection与Map接口•集合(collection)是个管理一组对象的单一对象。
在集合内的对象称之为元素(elements)。
通常,集合可以处理很多种类型的对象,这些类型的对象都属于一个特定的类型( 也就是说,它们具有共同的父类型)。
•集合API 包含了如下将对象组为一体的接口:●Collection ——一组称之为元素的对象;其实现决定了是否有特定的顺序和是否允许有重复元素。
●List——有顺序的集合;可允许元素重复●Set——没有顺序的集合;不允许元素重复元素的类型•在Java SE 5.0 发布以前,集合维护对Object 类型的对象的引用。
这可以使任何对象存放在集合内。
从集合中获取对象后,在使用之前必须先正确使用强制类型转换。
但是,到了Java SE 5.0 平台和以后版本,可以使用泛型集合功能指定要存放在集合中的对象类型。
避免了获取时做强制类型转换的麻烦。
Map 接口通用集合实现列表List•列表List是一个有顺序的Collection,允许有重复元素,主要实现类包括ArrayList和LinkedList,前者是顺序表,后者是链表。
•程序11-1 的示例中,程序声明了一个被赋予新的ArrayList 对象的List 类型的变量(list)。
然后添加一些元素,将list 印到标准输出。
因为List 允许有重复元素,程序11-1 的第10 行和第11 行的add 方法返回true。
列表List1 import java.util.*;2 public class ArrayListExample {3 public static void main(String[] args) {4 List list = new ArrayList();5 list.add("one");6 list.add("second");7 list.add("3rd");8 list.add(new Integer(4));9 list.add(new Float(5.0F));10 list.add("second"); // 重复,被添加11 list.add(new Integer(4)); // 重复,被添加12 System.out.println(list);13 }14 }集合Set•程序11-2 的示例中,程序声明了一个已初始化为new HashSet 的Set 类型的变量(set)。
然后添加一些元素,并将set打印到标准输出中。
程序11-2的第10 行和第11 行尝试对set添加重复的值。
因为重复值无法添加到Set,所以add 方法返回false。
使用泛型和集合框架第11章集合Set1 import java.util.*;2 public class SetExample {3 public static void main(String[] args) {4 Set set = new HashSet();5 set.add("one");6 set.add("second");7 set.add("3rd");8 set.add(new Integer(4));9 set.add(new Float(5.0F));10 set.add("second"); // 重复,不被添加11 set.add(new Integer(4)); // 重复,不被添加12 System.out.println(set);13 }14 }映射Map•Map 有时称之为关联数组。
Map 对象描述了键(key) 与值(value) 的映射关系。
根据定义,Map对象不允许重复键或空键,一个键最多只能对应一个值。
•Map 接口提供使映射内容被视为集合的三个方法:entrySet –返回包括所有键值对的集合keySet –返回映射所有键的集合values –返回包含映射内所有值的集合Map•Map 接口并没有继承Collection 接口,因为它代表了映射,而非对象的集合。
SortedMap 接口继承Map 接口。
实现Map接口的一些类有HashMap、TreeMap、IdentityHashMap 和WeakHashMap。
这些映射集合实现的迭代器所表示的顺序只针对每个特定的迭代器。
映射Map•程序11-3 的示例中,程序声明了一个Map 类型的变量map,并赋予它新的HashMap对象。
然后通过使用put操作添加一些元素。
为了证明map 不允许有重复键,程序尝试使用存在的键添加新的值。
这将导致以前添加的值被新的值取代。
随后程序使用集合查看操作keySet、values 和entrySet 获取map 的内容。
1 import java.util.*;2 public class MapExample {3 public static void main(String args[]) {4 Map map = new HashMap();5 map.put("one","1st");6 map.put("second", new Integer(2));7 map.put("third","3rd");8 // 重写前面的赋值9 map.put("third","III");10 // 返回键的集合11 Set set1 = map.keySet();12 // 返回值的集合13 Collection collection = map.values();14 // 返回键值映射的集合15 Set set2 = map.entrySet();16 System.out.println(set1 + "\n" + collection + ―\n‖ + set2);17 }18 }遗留的集合类•JDK 1.0和1.1版本的集合类仍然以同样的接口存在于当前的JDK 中,但它们已经被重组以便与新的集合API 交互。
Vector 类实现List 接口。
Stack 类是Vector 的扩展,添加了典型的堆栈操作Hashtable 类是Map 的实现。
Properties 类是Hashtable 的扩展•上述的每个集合都有返回枚举对象的elements 方法。
Enumeration 同Iterator 接口类似但不兼容。
例如hasNext 由枚举接口中的hasMoreElements 替代。
排序集合•Comparable 和Comparator 接口对于排序集合非常有用。
Comparable 接口为实现它的类提供自然排序。
Comparator接口用于指定顺序关系。
也可以用于覆盖自然排序。
这些接口对于集合元素的排序非常有用。
Comparable接口•Comparable 接口为ng 包内的成员。
当声明类时,JVM 实现无法确定此类对象所需的顺序。
通过实现Comparable 接口,可以为任意类的对象提供排序。
可以将包含实现Comparable 接口的类的对象排序。
实现Comparable 接口的一些Java 类的示例有Byte、Long、String、Date 和Float。
其中,number 类使用数字实现;String 类则使用字母实现,Date类使用时间顺序实现。
将包含String 类型元素的ArrayList 传递给集合类的静态排序方法,将返回按照字母顺序排序的列表。
包含Date 类型元素的列表按时间顺序排序。
包含Integer 类型元素的列表按数值大小排序。
要编写自定义的Comparable 类型,需要实现Comparable 接口的compareTo 方法。
•程序11-4 展示了如何实现Comparable 接口。
Student 类实现Comparable 接口以便此类的对象可以互相比较。
运行结果•StudentList 程序输出结果为:Name = Kelly Grant ID = 0 GPA = 2.3Name = John Lynn ID = 0 GPA = 2.8Name = Jim Max ID = 0 GPA = 3.6Name = Mike Hauffmamn ID = 0 GPA = 4.0•由观察得到学生是依照GPA 进行比较的。
这是因为当在TreeSet 集合中排序时,TreeSet查看对象是否有自然顺序,并且在这种情况下,使用compareTo 方法比较对象。
Comparator接口•有些集合,例如TreeSet 是被排序的。
TreeSet 实现需要知道如何将元素排序。
假如元素已经有自然排序,TreeSet 使用自然排序。
否则,必须协助排序。
例如,TreeSet 类有将Comparator 接收为参数的以下构造器:TreeSet(Comparator comparator)•此构造器会创建一个新的空树集合,依照指定的Comparator 来排序。
下面将会进一步讨论Comparator 接口的使用。
Comparator 接口•Comparator 接口对排序功能提供了很大的灵活性。
例如,如果认为以前描述的Student 类的排序受限于GPA 的分类,根据名字或一些其它标准对学生排序不太可能。
本部分将会展示使用Comparator 接口改善排序的灵活性。
•Comparator 接口是java.util 包的成员。
它用于在自定义排序而非自然排序中比较对象。
例如,它可以按照自然顺序以外的其它顺序将对象排序。
也可以用于将未实现Comparable 接口的对象分类。
•要编写自定义的Comparator,需要提供接口中compare 方法的实现:int compare(Object o1, Object o2)这个方法会比较两个参数的顺序。
如果第一个参数小于第二个参数则返回负数,如果两个相等返回零,如果第一个参数大于第二个参数则返回正数。
Comparator 接口实现示例•按firstName进行比较1 import java.util.*;2 public class NameComp implements Comparator {3 public int compare(Object o1, Object o2) {4 return5 (((Student)o1)pareTo(((Student)o2).firstName));6 }7 }按GPA比较1 import java.util.*;2 public class GradeComp implements Comparator {3 public int compare(Object o1, Object o2) {4 if (((Student)o1).GPA == ((Student)o2).GPA)5 return 0;6 else if (((Student)o1).GPA < ((Student)o2).GPA)7 return -1;8 else9 return 1;10 }11 }1 import java.util.*;2 public class ComparatorTest {3 public static void main(String[] args) {4 Comparator c = new NameComp();5 TreeSet studentSet = new TreeSet(c);6 studentSet.add(new Student("Mike", "Hauffmamn",101,4.0));7 studentSet.add(new Student("John", "Lynn",102,2.8 ));8 studentSet.add(new Student("Jim", "Max",103, 3.10));9 studentSet.add(new Student("Kelly", "Grant",104,2.3));10 Object[] studentArray = studentSet.toArray();11 Student s;12 for(Object obj : studentArray){13 s = (Student) obj;14 System.out.println("Name = %s %s ID = %d GPA =%f",15 s.firstName(), stName(), s.studentID(), s.GPA());16 = "+s.studentID+" GPA = "+s.GPA);17 }18 }19 }泛型•集合类使用Object 类型以允许不同的输入和返回类型。