JAVA学习基础之JAVA类集(java类中的类)

createh53个月前 (02-01)技术教程25

第十三章、JAVA类集

在JAVA中必须掌握的知识点,会开发的:

1、面向对象; 2、JAVA的类集; 3、JAVAIO; 4、JDBC;

13-1、认识类集、Collection接口

类集实际上就是一个动态的对象数组,与一般的对象数组不同,类集中的对象内容可以任意扩充。

类集的特征:

·这种框架是高性能的;

·框架必须允许不同类型的类集以相同的方式和高度互操作方式工作;

·类集必须是容易扩展和修改的;

对象数组中包含一组对象,但是对象数组使用的时候存在一个长度的限制,那么类集是专门解决这种限制的,使用类集可以方便的向数组中增加任意多个数据。

对象数组的操作中基本上都要保证对象类型的一致性,对于类集而言本身其内部的元素也应该保持一致,不管是何种类型的数据,所有的操作方式都应该是一样的。

类集框架主要接口

NO

接口

描述

1

Collection

是存放一组单值的最大接口,所谓的单值是指集合中的每个元素都是一个对象,一般很少会直接使用此接口直接操作。

2

List

是Collection接口的子接口,也是最常用的接口,此接口对Collection接口进行了大量的扩充,里面的内容是允许重复的。

3

Set

是Collection接口的子类,没有对Collection接口进行扩充,里面不允许存放重复内容。

4

Map

Map是存放一对值的最大接口,即,接口中的每个元素都是一对,以keyvalue的形式保存

5

Iterator

集合的输出接口,用于输出集合中的内容,只能进行从前到后的单向输出。

6

ListIterator

是Iterator的子接口,可以进行双向输出。

7

Enumeration

是最早的输出接口,用于输出指定集合中的内容。

8

SortedMap

存放一对值的排序接口,实现此接口的集合类,里面的内容按照key排序,使用比较器排序。

9

SortedSet

单值的排序接口,实现此接口的集合类,里面的内容是可以排序的,使用比较器排序。

10

Queue

队列接口,此接口的子类可以实现队列操作。

11

Map.Entry

Map.Entry的内部接口,每个Map.Entry对象都保存着一对keyvalue的内容,每个Map接口中都保存多个Map.Entry接口实例。

Collection接口的定义:

·Collection是保存单值集合的最大父接口;

·Collection接口定义:

·public interface Collection extends Iterable

·JDK1.5之后为Collection接口增加了泛型声明;

所有的类集操作都在java.util包中。

Collection接口的方法定义

NO

方法

类型

描述

1

public boolean add(E o)

普通

向集合中插入对象

2

public Boolean addAll(Collection c)

普通

将一个集合的内容插入进来

3

public void clear()

普通

清除此集合中的所有元素

4

public Boolean conlains(Object o)

普通

判断某一个对象是否在集合中存在

5

public Boolean containsAll(Collection c)

普通

判断一组对象是否在集合中存在

6

public Boolean equals(Object o)

普通

对象比较

7

public int hashCode()

普通

哈希码

8

public Boolean isEmpty()

普通

集合是否为空

9

public Iterator iterator()

普通

为Iterator接口实例化

10

public Boolean remove(Object o)

普通

删除指定对象

11

public Boolean removeAll(Collection c)

普通

删除一组对象

12

public Boolean retainAll(Collection c)

普通

保存指定内容

13

public int size()

普通

求出集合的大小

14

public Object[] toArray()

普通

将一个集合变为对象数组

15

public T[] toArray(T[] a)

普通

指定好返回的对象数组类型

Collection接口的使用注意:

·在一般的开发中,往往很少去直接使用Collection接口进行开发,而基本上都是使用其子接口。子接口主要有:List、Set、Queue、SortedSet。

之所以不使用Collection接口也是JAVA的逐步发展形成的,最早的时候实际上Collection接口被广泛使用,因为EJB技术的支持,在EJB2.x中大量的使用了Collection接口,但是随着发展,SUN公司开始将这些标准进行逐步的规范化,所以在SUN一个开源—宠物商店,基本上就不再直接使用Collection了,而是使用List或Set,这样来说可以更加清楚的表示出操作的类型。

Collection子接口的定义:Collection接口虽然是集合的最大接口,但是如果直接使用Collection接口进行操作的话,则表示的操作意义不明确,所以在JAVA开发中已经不提倡直接使用Collection接口了,主要的子接口如下:

·List接口:可以存放重复的内容

·Set接口:不能存放重复的内容,所有的重复内容是靠hashCode()和equals()两个方法区分的

·Queue:队列接口

·SortedSet接口:可以对集合中的数据进行排序

13-2、JAVA类集—List接口

Collection下分为很多的子接口,其中有一个List接口,List接口中可以存放任意的数据,而且在List接口中内容是允许重复的。

List是Collection的子接口,里面可以保存各个重复的内容,此接口的定义如下:

·public interface List extends Collection

List接口的扩展方法

NO

方法

类型

描述

1

public void add(int index,E element)

普通

在指定位置增加元素

2

public Boolean addAll(int index,Collection c)

普通

在指定位置增加一组元素

3

E get(int index)

普通

返回指定位置的元素

4

public int indexOf(Object o)

普通

查找指定元素的位置

5

public int lastIndexOf(Object o)

普通

从后向前查找指定元素的位置

6

public ListIterator listIterator()

普通

为ListIterator接口实例化

7

public E remove(int index)

普通

按指定的位置删除元素

8

public List subList(int fromIndex,int toIndex)

普通

取出集合中的子集合

9

public E set(int index,E element)

普通

替换指定位置的元素

List接口的常用子类——ArrayList

ArrayList是List子类,可以直接通过对象的多态性,为List接口实例化,此类的定义如下:

public class ArrayList extends AbstractList implements List,RandomAccess,Cloneable,Serializable

AbstractList类的定义如下:

public abstract class AbstractList extends AbstractCollection implements List

如果要想使用接口,则肯定要使用对象的多态性进行实例化的操作,那么对于List接口本身也是一样的。

ArrayList是List接口中最常用的子类。

import java.util.ArrayList ;

import java.util.List ;

public class ArrayListDemo01{

public static void main(String args[]){

List allList = null ;

allList = new ArrayList() ; // 指定操作的泛型为String

allCollection = new ArrayList() ; // 指定一个集合

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

System.out.println(allList) ;

}

};

在指定位置上增加一组数据:

import java.util.ArrayList ;

import java.util.List ;

import java.util.Collection ;

public class ArrayListDemo01{

public static void main(String args[]){

List allList = null ;

Collection allCollection = null ;

allList = new ArrayList() ; // 指定操作的泛型为String

allCollection = new ArrayList() ; // 指定一个集合

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

System.out.println(allList) ;

allCollection.add("LXH") ; // 向Collection中加入内容

allCollection.add("www.mldn.cn") ;

allList.addAll(allCollection) ;

allList.addAll(0,allCollection) ;

System.out.println(allList) ;

}

};

既然可以增加数据,那么自然也可以删除数据:

·List中存在两种删除:根据对象内容、根据对象的编号

import java.util.ArrayList ;

import java.util.List ;

public class ArrayListDemo02{

public static void main(String args[]){

List allList = null ;

allList = new ArrayList() ; // 指定操作的泛型为String

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

allList.add("MLDN") ; // 向Collection中加入内容

allList.add("www.mldn.cn") ;

allList.remove(0) ; // 删除第一个元素,指定删除的位置

allList.remove("Hello") ; // 此方法由Collection接口继承而来

System.out.println(allList) ;

}

};

集合中的内容可以添加,可以删除,那么实际上最重要的就是输出。

·在List接口中提供了get()方法,利用此方法就可以完成输出。

·通过循环完成输出,循环的次数由size()方法取得。

import java.util.ArrayList ;

import java.util.List ;

public class ArrayListDemo03{

public static void main(String args[]){

List allList = null ;

allList = new ArrayList() ; // 指定操作的泛型为String

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

allList.add("MLDN") ; // 向Collection中加入内容

allList.add("www.mldn.cn") ;

System.out.print("由前向后输出:") ;

for(int i=0;i

System.out.print(allList.get(i) + "、") ;

}

System.out.print("\n由后向前输出:") ;

for(int i=allList.size()-1;i>=0;i--){

System.out.print(allList.get(i) + "、") ;

}

}

};

此输出方式是List接口所独有的,而其他接口是没有的,尤其是Collection中是没有根据索引取出内容的操作。

import java.util.ArrayList ;

import java.util.List ;

public class ArrayListDemo04{

public static void main(String args[]){

List allList = null ;

allList = new ArrayList() ; // 指定操作的泛型为String

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

allList.add("MLDN") ; // 向Collection中加入内容

allList.add("www.mldn.cn") ;

String str[] = allList.toArray(new String[]{}) ; // 指定好类型

System.out.print("指定数组类型:") ;

for(int i=0;i

System.out.print(str[i] + "、") ;

}

System.out.print("\n返回对象数组:") ;

Object obj [] = allList.toArray() ; // 返回Object类型

for(int i=0;i

String temp = (String)obj[i] ; // 进行向下转型

System.out.print(temp + "、") ;

}

}

};

既然已经完成基本的输出的功能,集合中还有以下的几个操作:

·判断集合是否为空:boolean isEmpty()

·截取部分集合:List subList(int fromIndex,int toIndex),List接口扩充

·查找指定的对象是否存在:int indexOf(Object o),如果查找到则返回位置,否则返回-1

·查找是否存在:boolean contains(Object o)

import java.util.ArrayList ;

import java.util.List ;

public class ArrayListDemo05{

public static void main(String args[]){

List allList = null ;

allList = new ArrayList() ; // 指定操作的泛型为String

System.out.println("集合操作前是否为空?" + allList.isEmpty()) ;

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

allList.add("MLDN") ; // 向Collection中加入内容

allList.add("www.mldn.cn") ;

System.out.println(allList.contains("Hello")?"\"Hello\"字符串存在!" : "\"Hello\"字符串不存在!") ;

List allSub = allList.subList(2,3) ; // 字符串截取

System.out.println("集合截取:") ;

for(int i=0;i

System.out.print(allSub.get(i) + "、") ;

}

System.out.println("MLDN字符串的位置:" + allList.indexOf("MLDN")) ;

System.out.println("集合操作后是否为空?" + allList.isEmpty()) ;

}

};

挽救的子类:Vector

在List接口中还有一个子类:Vector,Vector类属于一个挽救的子类,从整个JAVA的集合发展历史来看,Vector算是一个元老级的类,在JDK1.0的时候已经存在此类.但是到了JAVA2(JDK1.2)之后重点强调了集合框架的概念,所以先后定义了很多的新接口(如:List等),但是考虑到了一大部分的人已经习惯了使用Vector类,所以JAVA的设计者,就让Vector类多实现了一个List接口,这才将其保留下来。但是因为其是List子类,所以Vector类的使用与之前的并没有太大的区别。

Vector类的定义:

·public class Vector extends AbstractListimplements List,RandomAccess,Cloneable,Serializable

import java.util.Vector ;

import java.util.List ;

public class VectorDemo01{

public static void main(String args[]){

List allList = null ;

allList = new Vector() ; // 指定操作的泛型为String

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add("Hello") ; // 此方法由Collection接口而来

allList.add(0,"World") ; // 在第一个位置上添加新的内容

allList.add("MLDN") ; // 向Collection中加入内容

allList.add("www.mldn.cn") ;

for(int i=0;i

System.out.print(allList.get(i) + "、") ;

}

}

};

因为Vector类本身属于旧的类,所以在类中也提供了很多重复的方法。

增加元素:public void addElement(E obj)此方法是最早的增加元素的操作,之后此方法的功能与add()方法是一致的。

import java.util.Vector ;

import java.util.List ;

public class VectorDemo02{

public static void main(String args[]){

Vector allList = null ;

allList = new Vector() ; // 指定操作的泛型为String

allList.addElement("Hello") ; // 此方法由Collection接口而来

allList.addElement("MLDN") ; // 向Collection中加入内容

allList.addElement("www.mldn.cn") ;

for(int i=0;i

System.out.print(allList.get(i) + "、") ;

}

}

};

那么ArrayList与Vector我们应该使用哪个类呢?

ArrayList与Vector的区别

NO

比较点

ArrayList

Vector

1

推出时间

JDK1.2之后推出的,属于新的操作类

JDK1.0时推出,属于旧的操作类

2

性能

采用异步处理方式,性能更高

采用同步处理方式,性能较低

3

线程安全

属于非线程安全的操作类

属于线程安全的操作类

4

输出

只能使用Iterator、foreach输出

可以使用Iterator、foreach、Enumeration输出

13-3、JAVA类集—LinkedList类

13-3-1、LinkedList子类与Queue接口

LinkedList表示的是一个链表的操作类,此类定义如下:

·public class LinkedList extends AbstractSequentialListimplements List,Queue,Cloneable,Serializable

Queue接口是Collection的子接口,此接口定义如下:

·public interface Queue extends Collection

Queue接口定义的方法

NO

方法

类型

描述

1

public E element()

普通

找到链表的表头

2

public Boolean offer(E o)

普通

将指定元素增加到链表的结尾

3

public E peek()

普通

找到但并不删除链表的头

4

public E poll()

普通

找到并删除此链表的头

5

public E remove()

普通

检索并移除表头

LinkedList中操作链表的部分方法

NO

方法

类型

描述

1

public void addFirst(E o)

普通

在链表开头增加元素

2

public void addLast(E o)

普通

在链表结尾增加元素

3

public Boolean offer(E o)

普通

将指定元素增加到链表的结尾

4

public E removeFirst()

普通

删除链表的第一个元素

5

public E removeLast()

普通

删除链表的最后一个元素

本身大量的扩充了Queue接口和List接口的操作,所以,在使用时最好直接使用LinkedList类完成操作。

为链表的开头和结尾增加数据

import java.util.LinkedList ;

public class LinkedListDemo01{

public static void main(String args[]){

LinkedList link = new LinkedList() ;

link.add("A") ; // 增加元素

link.add("B") ; // 增加元素

link.add("C") ; // 增加元素

System.out.println("初始化链表:" + link) ;

link.addFirst("X") ; // 在开头增加数据

link.addLast("Y") ; // 在结尾增加数据

System.out.println("增加头和尾之后的链表:" + link) ;

}

};

对于链表也可以找到其表头:

import java.util.LinkedList ;

public class LinkedListDemo02{

public static void main(String args[]){

LinkedList link = new LinkedList() ;

link.add("A") ; // 增加元素

link.add("B") ; // 增加元素

link.add("C") ; // 增加元素

System.out.println("1-1、element()方法找到表头:" + link.element()) ;

System.out.println("1-2、找完之后的链表的内容:" + link) ;

System.out.println("2-1、peek()方法找到表头:" + link.peek()) ;

System.out.println("2-2、找完之后的链表的内容:" + link) ;

System.out.println("3-1、poll()方法找到表头:" + link.poll()) ;

System.out.println("3-2、找完之后的链表的内容:" + link) ;


}

};

既然此类实现了Queue接口,那么就可以按照队列的方式进行FIFL的操作:

import java.util.LinkedList ;

public class LinkedListDemo03{

public static void main(String args[]){

LinkedList link = new LinkedList() ;

link.add("A") ; // 增加元素

link.add("B") ; // 增加元素

link.add("C") ; // 增加元素

System.out.print("以FIFO的方式输出:") ;

for(int i=0;i<=link.size()+1;i++){

System.out.print(link.poll() + "、") ;

}

}

};

13-4、JAVA类集—Set接口

Set接口也是Collection接口的子接口,但是与Collection或List接口不同的是,Set接口中不能加入重复的元素。

Set接口的定义:

·public interface Set extends Collection

Set接口的主要方法与Collection是一致的;

Set接口的实现无法像List接口那样进行双向输出;

Set接口的常用子类:

·散列存放:HashSet;使用散列的方式存放内容,本身没有顺序。

·有序存放:TreeSet

使用HashSet输入数据:

import java.util.HashSet ;

import java.util.Set ;

public class HashSetDemo01{

public static void main(String args[]){

Set allSet = new HashSet() ;

allSet.add("A") ; // 增加内容

allSet.add("B") ; // 增加内容

allSet.add("C") ; // 增加内容

allSet.add("C") ; // 重复内容

allSet.add("C") ; // 重复内容

allSet.add("D") ; // 增加内容

allSet.add("E") ; // 增加内容

System.out.println(allSet) ;

}

};

以上代码运行后显示的内容是无序排列的。而List接口的内容插入的顺序就是其保存的顺序。

如果希望所有的内容可以自动进行排序的操作,则可以使用Set中的第二个子类TreeSet。

import java.util.TreeSet ;

import java.util.Set ;

public class TreeSetDemo01{

public static void main(String args[]){

Set allSet = new TreeSet() ;

allSet.add("C") ; // 增加内容

allSet.add("C") ; // 重复内容

allSet.add("C") ; // 重复内容

allSet.add("D") ; // 增加内容

allSet.add("B") ; // 增加内容

allSet.add("A") ; // 增加内容

allSet.add("E") ; // 增加内容

System.out.println(allSet) ;

}

};

TreeSet子类是可以排序的。

13-5、JAVA类集—排序及重复元素说明

TreeSet类的内容是可以排序的,那么现在给出任意一个类,观察能否进行排序的操作:

import java.util.Set ;

import java.util.TreeSet ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

};

public class TreeSetDemo02{

public static void main(String args[]){

Set allSet = new TreeSet() ;

allSet.add(new Person("张三",30)) ;

allSet.add(new Person("李四",31)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("赵六",33)) ;

allSet.add(new Person("孙七",33)) ;

System.out.println(allSet) ;

}

};

执行时出现了以下的错误:

Exception in thread “main” java.lang.ClassCastException:Person cannot be cast to Java.lang.Comparable

at java.util.TreeMap.put(Unknown Source)

at java.util.TreeSet.add(Unknown Source)

at TreeSetDemo02.main(TreeSetDemo02.java:18)

Comparable之前曾经讲解过主要是进行排序的操作接口,一个对象数组要想排序,则依靠Comparable接口完成,那么对于TreeSet也一样,如果要想使用TreeSet进行排序的操作,则对象所在的类也必须实现Comparable接口。

import java.util.Set ;

import java.util.TreeSet ;

class Person implements Comparable{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

public int compareTo(Person per){

if(this.age>per.age){

return 1 ;

}else if(this.age

return -1 ;

}else{

return 0 ;

}

}

};

public class TreeSetDemo03{

public static void main(String args[]){

Set allSet = new TreeSet() ;

allSet.add(new Person("张三",30)) ;

allSet.add(new Person("赵六",25)) ;

allSet.add(new Person("孙七",25)) ;

allSet.add(new Person("李四",31)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

System.out.println(allSet) ;

}

};

String类既然可以使用TreeSet排序,则String中肯定已经实现了Comparable接口。

此时是可以排序了,但是结果有问题:

[姓名:赵六;年龄:25, 姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32]

发现此时去掉了重复的元素(在程序中,王五插入了三个),但是依靠的是Comparable接口完成的。孙七没有加进来,因为两个的年龄是完全一样的,而此时的Comparable接口比较的只是年龄,所以为了保证正确,所有的属性都应该进行比较:

import java.util.Set ;

import java.util.TreeSet ;

class Person implements Comparable{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

public int compareTo(Person per){

if(this.age>per.age){

return 1 ;

}else if(this.age

return -1 ;

}else{

return this.name.compareTo(per.name) ; // 调用String中的compareTo()方法

}

}

};

public class TreeSetDemo04{

public static void main(String args[]){

Set allSet = new TreeSet() ;

allSet.add(new Person("张三",30)) ;

allSet.add(new Person("赵六",25)) ;

allSet.add(new Person("孙七",25)) ;

allSet.add(new Person("李四",31)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

System.out.println(allSet) ;

}

};

运行结果:

[姓名:孙七;年龄:25, 姓名:赵六;年龄:25, 姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32]

此时去掉的重复元素是按姓名取消重复元素的。

现在采用HashSet接口写入数据,看看结果:

import java.util.Set ;

import java.util.HashSet ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

};

public class RepeatDemo01{

public static void main(String args[]){

Set allSet = new HashSet() ;

allSet.add(new Person("张三",30)) ;

allSet.add(new Person("赵六",25)) ;

allSet.add(new Person("孙七",25)) ;

allSet.add(new Person("李四",31)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

System.out.println(allSet) ;

}

};

运行结果:

[姓名:王五;年龄:32, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:张三;年龄:30, 姓名:王五;年龄:32, 姓名:赵六;年龄:25, 姓名:孙七;年龄:25]

此时,程序并没有去掉重复的元素,那么重复元素该如何取消呢?

如果要想取消掉重复元素,则需要Object类中的两个方法帮助:

·hashCode():表示一个唯一的编码,一般通过计算表示

·equals():进行对象的比较操作

import java.util.Set ;

import java.util.HashSet ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public boolean equals(Object obj){ // 覆写equals,完成对象比较

if(this==obj){

return true ;

}

if(!(obj instanceof Person)){

return false ;

}

Person p = (Person)obj ; // 向下转型

if(this.name.equals(p.name)&&this.age==p.age){

return true ;

}else{

return false ;

}

}

public int hashCode(){

return this.name.hashCode() * this.age ; // 定义一个公式

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

};

public class RepeatDemo02{

public static void main(String args[]){

Set allSet = new HashSet() ;

allSet.add(new Person("张三",30)) ;

allSet.add(new Person("赵六",25)) ;

allSet.add(new Person("孙七",25)) ;

allSet.add(new Person("李四",31)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

allSet.add(new Person("王五",32)) ;

System.out.println(allSet) ;

}

};

如果要想使用Set,则就必须注意以上的两个问题。

总结:

·一个好的类应该覆写Object类中的equals()、hashCode()、toString()三个方法,实际上在String中已经全部覆写完成了

·Set接口依靠hashCode()和equals()完成重复元素的判断,关于这一点在以后的Map接口中也有体现

·TreeSet依靠Comparable接口完成排序的操作

13-6、JAVA类集—SortedSet接口

从TreeSet类的定义中可以发现,TreeSet里实现了SortedSet接口,此接口主要是用于排序操作的,即:实现此接口的子类都属于排序的子类。SortedSet接口的定义如下:

·public interface SortedSet extends Set

SortedSet接口中定义的方法

NO

方法

类型

描述

1

public Comparator comparator()

普通

返回与排序有关联的比较器

2

public E first()

普通

返回集合中的第一个元素

3

public SortedSet headset(E toElement)

普通

返回从开始到指定元素的集合

4

public E last()

普通

返回最后一个元素

5

public SortedSet subset(E fromElement,E toElement)

普通

返回指定对象间的元素

6

public SortedSet tailSet(E fromElement)

普通

从指定元素到最后

操作实例:

import java.util.SortedSet ;

import java.util.TreeSet ;

public class TreeSetDemo05{

public static void main(String args[]){

SortedSet allSet = new TreeSet() ; //

allSet.add("A") ; // 增加内容

allSet.add("B") ; // 增加内容

allSet.add("C") ; // 增加内容

allSet.add("C") ; // 增加内容

allSet.add("C") ; // 增加内容

allSet.add("D") ; // 增加内容

allSet.add("E") ; // 增加内容

System.out.println("第一个元素:" + allSet.first()) ;

System.out.println("最后一个元素:" + allSet.last()) ;

System.out.println("headSet元素:" + allSet.headSet("C")) ;

System.out.println("tailSet元素:" + allSet.tailSet("C")) ;

System.out.println("subSet元素:" + allSet.subSet("B","D")) ;

}

};

13-7、JAVA类集—Iterator接口

在类集中提供了以下四种常见的输出方式:

·Iterator:迭代输出,是使用最多的输出方式

·ListIterator:是Iterator的子接口,专门用于输出List中的内容

·foreach输出:JDK1.5之后提供的新功能,可以输出数组或集合

·Enumeration输出:是一个旧的接口,功能与Iterator类似

对于Iterator而言,因为其本身是一个接口,所以要想实例化则必须依靠Collection接口完成。

Iterator iterator()

使用Iterator输出:

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class IteratorDemo01{

public static void main(String args[]){

List all= new ArrayList() ; //

all.add("hello") ;

all.add("_") ;

all.add("world") ;

Iterator iter = all.iterator() ; // 为Iterator接口实例化

while(iter.hasNext()){ // 判断是否有内容

System.out.println(iter.next()) ; // 输出内容

}

}

};

以上的操作代码属于Iterator的标准做法。

在Iterator接口中提供了remove()方法,此方法的功能是删除当前的对象:

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class IteratorDemo02{

public static void main(String args[]){

List all= new ArrayList() ; //

all.add("hello") ;

all.add("_") ;

all.add("world") ;

Iterator iter = all.iterator() ; // 为Iterator接口实例化

while(iter.hasNext()){ // 判断是否有内容

String str = iter.next() ;

if("_".equals(str)){

iter.remove() ; // 删除元素

}else{

System.out.println(str) ; // 输出内容

}

}

System.out.println("删除之后的集合:" + all) ;

}

};

在实际中Iterator是很少调用删除操作的,因为其本身的功能就是输出内容,当然,对于删除操作也有以下的一个注意点:

·List接口本身存在删除方法:remove

如果在使用迭代输出的过程中使用了List中的remove()执行删除操作,则代码将出现问题。

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class IteratorDemo03{

public static void main(String args[]){

List all= new ArrayList() ; //

all.add("hello") ;

all.add("_") ;

all.add("world") ;

Iterator iter = all.iterator() ; // 为Iterator接口实例化

while(iter.hasNext()){ // 判断是否有内容

String str = iter.next() ;

if("_".equals(str)){

all.remove(str) ; // 删除元素

}else{

System.out.println(str) ; // 输出内容

}

}

System.out.println("删除之后的集合:" + all) ;

}

};

在使用Iterator输出时,不要使用集合类中的remove()方法,而只能使用Iterator接口中的remove方法。

总结:

·Iterator接口的功能是从前向后输出,属于单向的输出

·Iterator的主要功能就是完成迭代输出操作的

·在使用Iterator的时候最好不要删除数据

13-8、JAVA类集—ListIterator接口

Iterator接口的主要功能是由前向后单向输出,而此时如果想实现由后向前或是由前向后的双向输出,则就必须使用Iterator的子接口——ListIterator。ListIterator接口定义如下:

·public interface ListIterator extends Iterator

虽然此接口可以进行双向的输出,但是遗憾的是Collection接口中并没有定义可以为此类实例化的操作,只有List接口中才存在了ListIterator接口的实例化操作。

范例:完成双向输出操作。

import java.util.ArrayList ;

import java.util.List ;

import java.util.ListIterator ;

public class ListIteratorDemo01{

public static void main(String argsp[]){

List all = new ArrayList() ;

all.add("hello") ;

all.add("_") ;

all.add("world") ;

ListIterator iter = all.listIterator() ;

System.out.print("由前向后输出:") ;

while(iter.hasNext()){

String str = iter.next() ;

System.out.print(str + "、") ;

}

System.out.print("\n由后向前输出:") ;

while(iter.hasPrevious()){

String str = iter.previous() ;

System.out.print(str + "、") ;

}

}

};

此时,已经完成了双向的输出操作。

但是,在使用此操作的时候一定要注意一点,一定要先进行由前后输出,之后才能进行由后向前的输出。

使用ListIterator还可以进行增加及替换元素:

·add()

·set()

import java.util.ArrayList ;

import java.util.List ;

import java.util.ListIterator ;

public class ListIteratorDemo02{

public static void main(String argsp[]){

List all = new ArrayList() ;

all.add("hello") ;

all.add("_") ;

all.add("world") ;

ListIterator iter = all.listIterator() ;

System.out.print("由前向后输出:") ;

while(iter.hasNext()){

String str = iter.next() ;

System.out.print(str + "、") ;

iter.set("LI - " + str) ; // 修改内容

}

System.out.print("\n由后向前输出:") ;

iter.add("LXH");

while(iter.hasPrevious()){

String str = iter.previous() ;

System.out.print(str + "、") ;

}

}

};

总结:

·如果要想使用ListIterator则只能依靠List接口完成

·如果要进行由后向前的输出,则只能先进行由前向后的输出

·对于此接口中的增加及修改操作了解即可

13-9、JAVA类集—foreach及Enumeration接口

JDK1.5之后增加了许多的功能,其中foreach可以输出数组,实际上foreach语法中也同样支持集合的输出操作:

import java.util.ArrayList;

import java.util.List;

public class ForeachDemo01{

public static void main(String args[]){

List all = new ArrayList() ;

all.add("hello") ;

all.add("_") ;

all.add("world") ;

for(String str:all){

System.out.print(str + "、") ;

}

}

};

实际上Iterator属于一个新的输出接口,在最早的JAVA刚出来的时候如果要想输出,使用Enumeration接口完成输出。

但是在JAVA中因为存在发展的历史问题,所以有些地方还会使用到Enumeration输出。

而且必须注意的是在使用Enumeration输出的时候一般都是直接操作Vector类完成的。

import java.util.Vector;

import java.util.Enumeration;

public class EnumerationDemo01{

public static void main(String args[]){

Vector all = new Vector() ;

all.add("hello") ;

all.add("_") ;

all.add("world") ;

Enumeration enu = all.elements() ;

while(enu.hasMoreElements()){ //判断是否有内容,hasNext()

System.out.print(enu.nextElement() + "、") ; // 输出元素:next()

}

}

};

总结:

·在所有的输出操作中,以Iterator接口为最标准的输出操作

·在部分旧的操作中Enumeration依然存在

13-10、JAVA类集—Map接口

之前接触的Collection、Set、List接口都属于单值的操作,即:每次只能操作一个对象,而Map与它们不同的是,每次操作的是一对对象,即二元偶对象,Map中的每个元素都使用keyvalue的形式存储在集合之中,此接口定义如下:

·public interface Map

Map接口中的方法

NO

方法或类

类型

描述

1

public void clear()

普通

清空Map集合

2

public boolean containsKey(Object key)

普通

判断指定的KEY是否存在

3

public boolean containsValue(Object value)

普通

判断指定的Value是否存在

4

public Set> entrySet()

普通

将Map对象变为Set集合

5

public Boolean equals(Object o)

普通

对象比较

6

public V get(Object key)

普通

根据key取得value

7

public int hashCode()

普通

返回哈希码

8

public boolean isEmpty()

普通

判断集合是否为空

9

public Set keySet()

普通

取得所有的key

10

pubic V put(K key,V value)

普通

向集合中加入元素

11

public void putAll(Map t)

普通

将一个Map集合中的内容加入到另一个Map

12

public V remove(Object key)

普通

根据key删除value

13

public int size()

普通

取出集合的长度

14

public Collection values()

普通

取出全部的value

Map.Entry是Map中内部定义的一个接口,专门用来保存keyvalue的内容。Map.Entry接口定义:

·public static interface Map.Entry

Map.Entry接口的常用方法

NO

方法或类

类型

描述

1

public boolean equals(Object o)

普通

对象比较

2

public K getKey()

普通

取得key

3

public V getValue()

普通

取得value

4

public int hashCode()

普通

返回哈希码

5

public V setValue(V value)

普通

设置value的值

Map接口的常用子类:

·HashMap:无序存放的,是新的操作类,key不允许重复

·Hashtable:无序存放的,是旧的操作类,key不允许重复

·TreeMap:可以排序的Map集合,按集合中的key排序,key不允许重复

·WeakHashMap:弱引用的Map集合,当集合中的某些内容不再使用时,可以清除掉无用的数据,可以使用gc进行回收

·IdentityHashMap:key可以重复的map集合

以HashMap为例,说明Map的基本方法操作:

import java.util.HashMap ;

import java.util.Map ;

public class HashMapDemo01{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new HashMap() ;

map.put("mldn","www.mldn.cn") ; // 增加内容

map.put("zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("mldnjava","www.mldnjava.cn") ; // 增加内容

String val = map.get("mldn") ; // 根据key取出值

System.out.println("取出的内容是:" + val) ;

}

};

在map中也可以使用containsXxx()方法判断指定的key或者value是否存在。

import java.util.HashMap ;

import java.util.Map ;

public class HashMapDemo02{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new HashMap() ;

map.put("mldn","www.mldn.cn") ; // 增加内容

map.put("zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("mldnjava","www.mldnjava.cn") ; // 增加内容

if(map.containsKey("mldn")){ // 判断key是否存在

System.out.println("搜索的key存在!") ;

}else{

System.out.println("搜索的key不存在!") ;

}

if(map.containsValue("www.mldn.cn")){ // 判断value是否存在

System.out.println("搜索的value存在!") ;

}else{

System.out.println("搜索的value不存在!") ;

}

}

};

如果现在要输出全部的key,则使用如下方法:

·Set keySet()

import java.util.HashMap ;

import java.util.Map ;

import java.util.Iterator ;

import java.util.Set ;

public class HashMapDemo03{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new HashMap() ;

map.put("mldn","www.mldn.cn") ; // 增加内容

map.put("zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("mldnjava","www.mldnjava.cn") ; // 增加内容

Set keys = map.keySet() ; // 得到全部的key

Iterator iter = keys.iterator() ;

while(iter.hasNext()){

String str = iter.next() ;

System.out.print(str + "、") ;

}

}

};

既然可以输出全部的key,那么就肯定可以输出全部的value。

·Collection values()

import java.util.HashMap ;

import java.util.Map ;

import java.util.Iterator ;

import java.util.Collection ;

public class HashMapDemo04{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new HashMap() ;

map.put("mldn","www.mldn.cn") ; // 增加内容

map.put("zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("mldnjava","www.mldnjava.cn") ; // 增加内容

Collection values = map.values() ; // 得到全部的value

Iterator iter = values.iterator() ;

while(iter.hasNext()){

String str = iter.next() ;

System.out.print(str + "、") ;

}

}

};

在Map中也存在一个Hashtable子类,实际上这个子类的推出时间与Vector是一样的,都属于旧的类。

HashMap与Hashtable的区别

NO

比较点

HashMap

Hashtble

1

推出时间

JDK1.2之后推出,属于新的操作类

JDK1.0时推出,属于旧的操作类

2

性能

采用异步处理方式,性能更高

采用同步处理方式,性能较低

3

线程安全

属于非线程安全的操作类

属于线程安全的操作类

在Map中还存在一个TreeMap的子类,此类也属于排序类,按key排序。

import java.util.TreeMap ;

import java.util.Map ;

import java.util.Set ;

import java.util.Iterator ;

import java.util.Collection ;

public class TreeMapDemo01{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new TreeMap() ;

map.put("A、mldn","www.mldn.cn") ; // 增加内容

map.put("C、zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("B、mldnjava","www.mldnjava.cn") ; // 增加内容

Set keys = map.keySet() ; // 得到全部的key

Iterator iter = keys.iterator() ;

while(iter.hasNext()){

String str = iter.next() ;

System.out.println(str + " --> " + map.get(str)) ; // 取出内容

}

}

};

使用TreeMap可以方便的完成排序的操作。如果自定义的类要想做为key的话,则肯定要实现Comparable接口,指定比较的规则。

弱引用类:WeakHashMap

之前的Map子类中的数据都是使用强引用保存的,即:里面的内容不管是否使用都始终在集合中保留,如果希望集合可以自动清理暂时不用的数据就可以使用WeakHashMap类。WeakHashMap的定义如下:

·public class WeakHashMapextends AbstractMapimplements Map

如果假设一个Map中的某些内容长时间不使用的话,按照之前的做法是不会删除掉的,如果希望其可以自动删除掉,可以使用弱引用。当里面的某些内容不使用时,可以自动删除掉。

import java.util.WeakHashMap ;

import java.util.Map ;

import java.util.Set ;

import java.util.Iterator ;

import java.util.Collection ;

public class WeakHashMapDemo01{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new WeakHashMap() ;

map.put(new String("mldn"),new String("www.mldn.cn")) ;

map.put(new String("zhinangtuan"),new String("www.zhinangtuan.net.cn")) ;

map.put(new String("mldnjava"),new String("www.mldnjava.cn")) ;

System.gc() ; // 强制性进行垃圾的收集操作

map.put(new String("cyg"),new String("chenyegen")) ;

System.out.println(map) ;

}

};

提示:对象的引用强度说明

从JDK1.2版本开始,JAVA把对象的引用分为四种级别,从而使程式能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:

·强引用:当内存不足时,JVM宁可出现OutOfMemeryError错误而使程序停止,也不会回收此对象来释放空间;

·软引用:当内存不足时,会回收这些对象的内存,用来实现内存敏感的高速缓存;

·弱引用:无论内存是否紧张,被垃圾回收器发现立即回收;

·虚引用:和没有任何引用一样。

13-11、JAVA类集—Map接口使用的注意事项

Map接口输出:

对于Map接口来说,其本身是不能直接使用迭代(例如:Iterator、foreach)进行输出的,因为Map中的每个位置存放的是一对值(keyvalue),而Iterator中每次只能找到一个值,所以,如果此时非要使用迭代进行输出的话,则必须按照以下的步骤完成(以Iterator输出方法为例):

·1、将Map的实例通过entrySet()方法变为Set接口对象;

·2、通过Set接口实例为Iterator实例化;

·3、通过Iterator迭代输出,每个内容都是Map.Entry的对象;

·4、通过Map.Entry进行keyvalue的分离。

但是在操作前必须说明的是:Map接口一般只作为查找使用,输出的操作毕竟属于少数。

import java.util.HashMap ;

import java.util.Map ;

import java.util.Set ;

import java.util.Iterator ;

public class IteratorDemo04{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new HashMap() ;

map.put("mldn","www.mldn.cn") ; // 增加内容

map.put("zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("mldnjava","www.mldnjava.cn") ; // 增加内容

Set> allSet = null ;

allSet = map.entrySet() ;

Iterator> iter = null ;

iter = allSet.iterator() ;

while(iter.hasNext()){

Map.Entry me = iter.next() ;

System.out.println(me.getKey() + " --> " + me.getValue()) ;

}

}

};

第一种方式,使用Iterator完成。当然在JDK1.5之后也可以使用foreach完成。

import java.util.HashMap ;

import java.util.Map ;

import java.util.Set ;

import java.util.Iterator ;

public class ForeachDemo02{

public static void main(String args[]){

Map map = null; // 声明Map对象,其中key和value的类型为String

map = new HashMap() ;

map.put("mldn","www.mldn.cn") ; // 增加内容

map.put("zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容

map.put("mldnjava","www.mldnjava.cn") ; // 增加内容

for(Map.Entry me:map.entrySet()){

System.out.println(me.getKey() + " --> " + me.getValue()) ;

}

}

};

这两种输出形式最终实际上还是以Collection的形式输出,只是以Map.Entry作为内容的操作类型。

在MAP中,可以使用任意类型作为key和value,那么使用非系统类也可以。

import java.util.Map ;

import java.util.HashMap ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

};

public class HashMapDemo05{

public static void main(String args[]){

Map map = null ;

map = new HashMap() ;

map.put("zhangsan",new Person("张三",30)); // 增加内容

System.out.println(map.get("zhangsan")) ;

}

};

如果现在以String为key是可以取出内容的。

import java.util.Map ;

import java.util.HashMap ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

};

public class HashMapDemo06{

public static void main(String args[]){

Map map = null ;

map = new HashMap() ;

map.put(new Person("张三",30),"zhangsan"); // 增加内容

System.out.println(map.get(new Person("张三",30))) ;

}

};

此时,只是将自定义的类作为key,但是在取值的时候发现取不了了,返回的结果是null,那么为什么之前的String可以,但是自定义的类不存在呢?

实际上,对于匹配过程来讲,有一个特点,即:对象要一样才可以将内容查询出来。

import java.util.Map ;

import java.util.HashMap ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

};

public class HashMapDemo07{

public static void main(String args[]){

Map map = null ;

map = new HashMap() ;

Person per = new Person("张三",30) ;

map.put(per,"zhangsan"); // 增加内容

System.out.println(map.get(per)) ;

}

};

可是这样并不是解决问题的方法,因为不可能将Person的per对象到处带着走啊,应该像String一样,可以使用匿名对象的形式找到内容。那么此时,实际上就需要按照与Set接口中判断重复元素的方式一样,进行方法的覆写。

  • 注意事项二:直接使用非系统类作为key

如果要使用非系统类作为Map的key,则此类必须覆写Object类中的以下两个方法:

·hashCode()

·equals

import java.util.Map ;

import java.util.HashMap ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public String toString(){

return "姓名:" + this.name + ";年龄:" + this.age ;

}

public boolean equals(Object obj){

if(this==obj){

return true ;

}

if(!(obj instanceof Person)){

return false ;

}

Person p = (Person)obj ;

if(this.name.equals(p.name)&&this.age==p.age){

return true ;

}else{

return false ;

}

}

public int hashCode(){

return this.name.hashCode() * this.age ;

}

};

public class HashMapDemo08{

public static void main(String args[]){

Map map = null ;

map = new HashMap() ;

map.put(new Person("张三",30),"zhangsan"); // 增加内容

System.out.println(map.get(new Person("张三",30))) ;

}

};

作为key,或者更准确的说是作为对象的时候,实际上是依靠hashCode()和equals()判断两个匿名对象是否相等,这一点由系统内部自动完成。

总结:

1、Map可以使用迭代输出

·mapentrySetSetIteratorMap.Entrykey和value

2、如果使用非系统类作为key,则一定保证覆写equals和hashCode()方法,否则无效。

13-12、JAVA类集—IdentityHashMap类

在正常的Map操作中,key本身是不能够重复的:

import java.util.IdentityHashMap ;

import java.util.HashMap ;

import java.util.Set ;

import java.util.Iterator ;

import java.util.Map ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public boolean equals(Object obj){

if(this==obj){

return true ;

}

if(!(obj instanceof Person)){

return false ;

}

Person p = (Person)obj ;

if(this.name.equals(p.name)&&this.age==p.age){

return true ;

}else{

return false ;

}

}

public int hashCode(){

return this.name.hashCode() * this.age ;

}

public String toString(){

return "姓名:" + this.name + ",年龄:" + this.age ;

}

};

public class IdentityHashMapDemo01{

public static void main(String args[]){

Map map = null ; // 声明Map对象

map = new HashMap() ;

map.put(new Person("张三",30),"zhangsan_1") ; // 加入内容

map.put(new Person("张三",30),"zhangsan_2") ; // 加入内容

map.put(new Person("李四",31),"lisi") ; // 加入内容

Set> allSet = null ; // 准备使用Set接收全部内容

allSet = map.entrySet() ;

Iterator> iter = null ;

iter = allSet.iterator() ;

while(iter.hasNext()){

Map.Entry me = iter.next() ;

System.out.println(me.getKey() + " --> " + me.getValue()) ;

}

}

};

使用HashMap操作的时候,key内容是不能重复的,如果现在希望key的内容可以重复(这里的重复是指两个对象的地址不一样key1= =key2)则要使用IdentityHashMap类。

import java.util.IdentityHashMap ;

import java.util.Set ;

import java.util.Iterator ;

import java.util.Map ;

class Person{

private String name ;

private int age ;

public Person(String name,int age){

this.name = name ;

this.age = age ;

}

public boolean equals(Object obj){

if(this==obj){

return true ;

}

if(!(obj instanceof Person)){

return false ;

}

Person p = (Person)obj ;

if(this.name.equals(p.name)&&this.age==p.age){

return true ;

}else{

return false ;

}

}

public int hashCode(){

return this.name.hashCode() * this.age ;

}

public String toString(){

return "姓名:" + this.name + ",年龄:" + this.age ;

}

};

public class IdentityHashMapDemo02{

public static void main(String args[]){

Map map = null ; // 声明Map对象

map = new IdentityHashMap() ;

map.put(new Person("张三",30),"zhangsan_1") ; // 加入内容

map.put(new Person("张三",30),"zhangsan_2") ; // 加入内容

map.put(new Person("李四",31),"lisi") ; // 加入内容

Set> allSet = null ; // 准备使用Set接收全部内容

allSet = map.entrySet() ;

Iterator> iter = null ;

iter = allSet.iterator() ;

while(iter.hasNext()){

Map.Entry me = iter.next() ;

System.out.println(me.getKey() + " --> " + me.getValue()) ;

}

}

};

就算是两个对象的内容相等,但是因为都使用了new关键字,所以地址肯定不等,那么就可以加入进去,key是可以重复的。

总结:

了解IdentityHashMap类的作用即可,在实际中此类使用的非常少。

13-13、JAVA类集—SortedMap接口

回顾:SortedSet,是TreeSet的实现接口,那么此接口可以进行排序的操作。

SortedMap也是排序的操作,之前学习过TreeMap类,那么此类是可以排序的。

SortedMap接口扩展的方法

NO

方法

类型

描述

1

public Comparator comparator()

普通

返回比较器对象

2

public K firstKey()

普通

返回第一个元素的key

3

public SortedMapheadMap(K toKey)

普通

返回小于等于指定key的部分集合

4

public K lastKey()

普通

返回厚后一个元素的key

5

public SortedMap subMap(K fromKey,K toKey)

普通

返回指定key范围的集合

6

public SortedMap tailMap(K fromKey)

普通

返回大于指定key的部分集合

范例:

import java.util.Map ;

import java.util.SortedMap ;

import java.util.TreeMap ;

public class SortedMapDemo{

public static void main(String args[]){

SortedMap map = null ;

map = new TreeMap() ; // 通过子类实例化接口对象

map.put("D、jiangker","http://www.jiangker.com/") ;

map.put("A、mldn","www.mldn.cn") ;

map.put("C、zhinangtuan","www.zhinangtuan.net.cn") ;

map.put("B、mldnjava","www.mldnjava.cn") ;

System.out.print("第一个元素的内容的key:" + map.firstKey()) ;

System.out.println(":对应的值:" + map.get(map.firstKey())) ;

System.out.print("最后一个元素的内容的key:" + map.lastKey()) ;

System.out.println(":对应的值:" + map.get(map.lastKey())) ;

System.out.println("返回小于指定范围的集合:") ;

for(Map.Entry me:map.headMap("B、mldnjava").entrySet()){

System.out.println("\t|- " + me.getKey() + " --> " + me.getValue()) ;

}

System.out.println("返回大于指定范围的集合:") ;

for(Map.Entry me:map.tailMap("B、mldnjava").entrySet()){

System.out.println("\t|- " + me.getKey() + " --> " + me.getValue()) ;

}

System.out.println("部分集合:") ;

for(Map.Entry me:map.subMap("A、mldn","C、zhinangtuan").entrySet()){

System.out.println("\t|- " + me.getKey() + " --> " + me.getValue()) ;

}

}

};

13-14、JAVA类集—集合工具类:Collections

Collections类与Collection没有直接关系,但是与集合中的各个接口都有操作的方法支持。

Collections类的常用方法及常量

NO

方法

类型

描述

1

public static final List EMPTY_LIST

常量

返回一个空的List集合

2

public static final Set EMPTY_SET

常量

返回空的Set集合

3

public static final Map EMPTY_MAP

常量

返回空的Map集合

4

public static boolean addAll(Collection c,T…a)

普通

为集合添加内容

5

public static > T max(Collection coll)

普通

找到最大的内容,按比较器排序

6

public static > T min(Collection coll)

普通

找到集合中的最小内容,按比较器排序

7

public static boolean replaceAll(List list,T oldVal,T newVal)

普通

用新的内容替换集合的指定内容

8

public static void reverse(List list)

普通

集合反转

9

public static int binarySearch(List> list,T key)

普通

查找集合中的指定内容

10

public static final List emptyList()

普通

返回一个空的List集合

11

public static final Map emptyMap()

普通

返回一个空的Map集合

12

public static final Set emptySet()

普通

返回一个空的Set集合

13

public static > void sort(List list)

普通

集合排序操作,根据Comparable接口进行排序

14

public static void swap(List list,int i,int j)

普通

交换指定位置的元素

验证,空集合的操作:

·public static final List emptyList()

·public static final Set emptySet()

import java.util.Collections ;

import java.util.List ;

import java.util.Set ;

public class CollectionsDemo01{

public static void main(String args[]){

List allList = Collections.emptyList() ; // 返回空的 List集合

Set allSet = Collections.emptySet() ; // 返回空的 List集合

allList.add("Hello") ; // 加入数据

}

};

如果要想为集合中增加内容,则肯定使用add()方法,在Collections中也提供了专门的增加操作。

public static Boolean addAll(Collection c,T…elements)

使用了可变参数,所以可以任意输入各种类型的数据。

import java.util.Collections ;

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class CollectionsDemo02{

public static void main(String args[]){

List all = new ArrayList() ; // 返回空的 List集合

Collections.addAll(all,"MLDN","LXH","mldnjava") ;

Iterator iter = all.iterator() ;

while(iter.hasNext()){

System.out.print(iter.next() + "、") ;

}

}

};

选择何种的加入操作根据个人喜好。

内容反转操作:

import java.util.Collections ;

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class CollectionsDemo03{

public static void main(String args[]){

List all = new ArrayList() ; // 返回空的 List集合

Collections.addAll(all,"MLDN","LXH","mldnjava") ;

Collections.reverse(all) ; // 内容反转

Iterator iter = all.iterator() ;

while(iter.hasNext()){

System.out.print(iter.next() + "、") ;

}

}

};

在Collections中也提供了二分检索的方法:

public static int binarySearch(List> list,T key)

完成检索:

import java.util.Collections ;

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class CollectionsDemo04{

public static void main(String args[]){

List all = new ArrayList() ; // 返回空的 List集合

Collections.addAll(all,"MLDN","LXH","mldnjava") ;

int point = Collections.binarySearch(all,"LXH") ; // 检索数据

System.out.println("检索结果:" + point) ;


}

};

替换内容:

public static boolean replaceAll(List list,T oldVal,T newVal)

执行替换操作:

import java.util.Collections ;

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class CollectionsDemo05{

public static void main(String args[]){

List all = new ArrayList() ; // 返回空的 List集合

Collections.addAll(all,"MLDN","LXH","mldnjava") ;

if(Collections.replaceAll(all,"LXH","李兴华")){// 替换内容

System.out.println("内容替换成功!") ;

}

System.out.print("替换之后的结果:") ;

System.out.print(all) ;


}

};

之前曾经说过,使用TreeSet可以进行排序操作,那么在Colletions类中也提供了这样的一个排序操作:

public static > void sort(List list)

实现排序功能:

import java.util.Collections ;

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class CollectionsDemo06{

public static void main(String args[]){

List all = new ArrayList() ; // 返回空的 List集合

Collections.addAll(all,"1、MLDN","2、LXH","3、mldnjava") ;

Collections.addAll(all,"B、www.mldn.cn") ;

Collections.addAll(all,"A、www.mldnjava.cn") ;

System.out.println("排序之前的集合:" + all) ;

Collections.sort(all) ;

System.out.println("排序之后的集合:" + all) ;


}

};

如果要进行排序的话,是肯定对象所在的类必须实现Comparable接口。

交换指定位置的内容:

public static void swap(List list,int i,int j)

完成一个交换内容的操作:

import java.util.Collections ;

import java.util.List ;

import java.util.ArrayList ;

import java.util.Iterator ;

public class CollectionsDemo07{

public static void main(String args[]){

List all = new ArrayList() ; // 返回空的 List集合

Collections.addAll(all,"1、MLDN","2、LXH","3、mldnjava") ;

System.out.println("交换之前的集合:" + all) ;

Collections.swap(all,0,2) ;

System.out.println("交换之后的集合:" + all) ;


}

};

总结:

1、在类集中为了方便集合的操作,提供了Collections类,此类与Collection接口没有直接的继承或实现关系,只是对所有的接口有所支持而已;

2、开发中是否使用此类没有明确的规定,按照个人的喜好执行即可。

13-15、JAVA类集—Stack类

栈是采用先进后出的数据存储方式,每一个栈都包含一个栈顶,每次出栈是将栈顶的数据取出:

在JAVA中使用Stack类进行栈的操作,Stack类是Vector的子类,Stack的定义如下:

·public class Stack extends Vector

Stack类的常用方法

NO

方法

类型

描述

1

public boolean empty()

常量

测试栈是否为空

2

public E peek()

常量

查看栈顶,但不删除

3

public E pop()

常量

出栈,同时删除

4

public E push(E item)

普通

入栈

5

public int search(Object o)

普通

在栈中查找

是Vector的一个子类。

import java.util.Stack ;

public class StackDemo{

public static void main(String args[]){

Stack s = new Stack() ;

s.push("A") ; // 入栈

s.push("B") ; // 入栈

s.push("C") ; // 入栈

System.out.print(s.pop() + "、") ;

System.out.print(s.pop() + "、") ;

System.out.println(s.pop() + "、") ;

System.out.println(s.pop()) ;

}

};

如果栈中已经没有内容了,则无法继续出栈。

13-16、JAVA类集—属性类:Properties

属性是在程序中经常出现的一种形式。

在类集中提供了一个专门的Properties类,以完成属性的操作。

public class Properties extends Hashtable

Properties是Hashtable的子类,则也是Map的子类,可以使用Map的全部操作,但是一般情况下属性类是单独使用的。

设置和取得属性:

设置属性:

public Object setProperty(String key,String value)

得到属性:

public String getProperty(String key)

public String getProperty(String key,String defaultValue)

验证以上操作:

import java.util.Properties;

public class PropertiesDemo01{

public static void main(String args[]){

Properties pro = new Properties() ; // 创建Properties对象

pro.setProperty("BJ","BeiJing") ; // 设置属性

pro.setProperty("TJ","TianJin") ;

pro.setProperty("NJ","NanJing") ;

System.out.println("1、BJ属性存在:" + pro.getProperty("BJ")) ;

System.out.println("2、SC属性不存在:" + pro.getProperty("SC")) ;

System.out.println("3、SC属性不存在,同时设置显示的默认值:" + pro.getProperty("SC","没有发现")) ;

}

};

属性操作中以上属于设置和读取属性,当然,对于属性中也可以将属性保存在文件之中。提供了以下的方法:

public void store(OutputStream out,String comments) throws IOException

将以上的属性写入到d:\area.properties文件中。

import java.util.Properties;

import java.io.File;

import java.io.FileOutputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

public class PropertiesDemo02{

public static void main(String args[]){

Properties pro = new Properties() ; // 创建Properties对象

pro.setProperty("BJ","BeiJing") ; // 设置属性

pro.setProperty("TJ","TianJin") ;

pro.setProperty("NJ","NanJing") ;

File file = new File("D:" + File.separator + "area.properteis") ; // 指定要操作的文件

try{

pro.store(new FileOutputStream(file),"Area Info") ; // 保存属性到普通文件

}catch(FileNotFoundException e){

e.printStackTrace() ;

}catch(IOException e){

e.printStackTrace() ;

}

}

};

此时已经将属性内容保存在了文件之中,既然可以保存,那么就可以读取。

public void load(InputStream inStream) throws IOException

使用以上方法读取属性内容。

import java.util.Properties;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

public class PropertiesDemo03{

public static void main(String args[]){

Properties pro = new Properties() ; // 创建Properties对象

File file = new File("D:" + File.separator + "area.properteis") ; // 指定要操作的文件

try{

pro.load(new FileInputStream(file)) ; // 读取属性文件

}catch(FileNotFoundException e){

e.printStackTrace() ;

}catch(IOException e){

e.printStackTrace() ;

}

System.out.println("1、BJ属性存在:" + pro.getProperty("BJ")) ;

System.out.println("2、SH属性存在:" + pro.getProperty("SH")) ;

}

};

以上是全部保存在了普通的文件之中,实际上在Properties操作的时候也可以将内容全部保存在XML文件之中。

import java.util.Properties;

import java.io.File;

import java.io.FileOutputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

public class PropertiesDemo04{

public static void main(String args[]){

Properties pro = new Properties() ; // 创建Properties对象

pro.setProperty("BJ","BeiJing") ; // 设置属性

pro.setProperty("TJ","TianJin") ;

pro.setProperty("NJ","NanJing") ;

File file = new File("D:" + File.separator + "area.xml") ; // 指定要操作的文件

try{

pro.storeToXML(new FileOutputStream(file),"Area Info") ; // 保存属性到普通文件

}catch(FileNotFoundException e){

e.printStackTrace() ;

}catch(IOException e){

e.printStackTrace() ;

}

}

};

既然可以使用XML文件格式保存,那么就可以使用XML文件读取内容。

import java.util.Properties;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

public class PropertiesDemo05{

public static void main(String args[]){

Properties pro = new Properties() ; // 创建Properties对象

File file = new File("D:" + File.separator + "area.xml") ; // 指定要操作的文件

try{

pro.loadFromXML(new FileInputStream(file)) ; // 读取属性文件

}catch(FileNotFoundException e){

e.printStackTrace() ;

}catch(IOException e){

e.printStackTrace() ;

}

System.out.println("1、BJ属性存在:" + pro.getProperty("BJ")) ;

}

};

总结:

1、如果要进一步了解属性操作,则可以继续学习后续的反射机制部分,了解属性类的应用。

2、属性中的类型肯定都是字符串,因为操作最方便。

3、属性可以向普通文件或XML文件中保存或读取,按照指定格式可以向文件中任意扩充属性。

13-17、JAVA类集—范例(一):一对多关系

实例要求:

使用类集可以表示出以下的关系:一个学校可以包含多个学生,一个学生属于一个学校,那么这就是一个典型的一对多关系,此时就可以通过类集进行关系的表示。

一个学校有多个学生,那么学生的个数属于未知的,这样一来肯定无法用普通的对象数组表示,必须通过类集表示。

学生类:

public class Student{

private String name ;

private int age ;

private School school; // 一个学生属于一个学校

public Student(String name,int age){

this.setName(name) ;

this.setAge(age) ;

}

public void setSchool(School school){

this.school = school ;

}

public School getSchool(){

return this.school ;

}

public void setName(String name){

this.name = name ;

}

public void setAge(int age){

this.age = age ;

}

public String getName(){

return this.name;

}

public int getAge(){

return this.age ;

}

public String toString(){

return "学生姓名:" + this.name + ";年龄:" + this.age ;

}

};

学校类:

import java.util.List ;

import java.util.ArrayList ;

public class School{

private String name ;

private List allStudents ;

public School(){

this.allStudents = new ArrayList() ;

}

public School(String name){

this() ;

this.setName(name) ;

}

public void setName(String name){

this.name = name ;

}

public String getName(){

return this.name;

}

public List getAllStudents(){

return this.allStudents ;

}

public String toString(){

return "学校名称:" + this.name ;

}

};

主类:

import java.util.Iterator ;

public class TestDemo{

public static void main(String args[]){

School sch = new School("清华大学") ; // 定义学校

Student s1 = new Student("张三",21) ;

Student s2 = new Student("李四",22) ;

Student s3 = new Student("王五",23) ;

sch.getAllStudents().add(s1) ;

sch.getAllStudents().add(s2) ;

sch.getAllStudents().add(s3) ;

s1.setSchool(sch) ;

s2.setSchool(sch) ;

s3.setSchool(sch) ;

System.out.println(sch) ;

Iterator iter = sch.getAllStudents().iterator() ;

while(iter.hasNext()){

System.out.println("\t|- " + iter.next()) ;

}

}

};

总结:

明白类集的关系,这种关系将成为日后标准程序的开发基础。

13-18、JAVA类集—范例(二):多对多关系

实例要求:

·一个学生可以选多门课程,一门课程可以有多个学生参加,那么这就是个典型的多对多关系。

·要完成本程序,首先应该定义两个类:学生信息类Student、课程信息类Course,在一个学生类中存在一个集合,保存全部的课程,而在课程类中也要存在一个集合,保存全部的学生。

学生类:

import java.util.List ;

import java.util.ArrayList ;

public class Student{

private String name ;

private int age ;

private List allCourses ;

public Student(){

this.allCourses = new ArrayList() ;

}

public Student(String name,int age){

this() ;

this.name = name ;

this.age = age ;

}

public List getAllCourses(){

return this.allCourses ;

}

public void setName(String name){

this.name = name ;

}

public void setAge(int age){

this.age = age ;

}

public String getName(){

return this.name ;

}

public int getAge(){

return this.age ;

}

public String toString(){

return "学生姓名:" + this.name + ";年龄:" + this.age ;

}

};

课程成绩类:

import java.util.List ;

import java.util.ArrayList ;

public class Course{

private String name ;

private int credit ;

private List allStudents ;

public Course(){

this.allStudents = new ArrayList() ;

}

public Course(String name,int credit){

this() ;

this.name = name ;

this.credit = credit ;

}

public List getAllStudents(){

return this.allStudents ;

}

public void setName(String name){

this.name = name ;

}

public void setCredit(int credit){

this.credit = credit ;

}

public String getName(){

return this.name ;

}

public int getCredit(){

return this.credit ;

}

public String toString(){

return "课程名称:" + this.name + ";课程学分:" + this.credit ;

}

};

主类:

import java.util.Iterator ;

public class TestMore{

public static void main(String args[]){

Course c1 = new Course("英语",3 ) ; // 第一门课程

Course c2 = new Course("计算机",5) ; // 第二门课程

Student s1 = new Student("张三",20) ;

Student s2 = new Student("李四",21) ;

Student s3 = new Student("王五",22) ;

Student s4 = new Student("赵六",23) ;

Student s5 = new Student("孙七",24) ;

Student s6 = new Student("钱八",24) ;

// 第一门课程有三个学生参加

c1.getAllStudents().add(s1) ;

c1.getAllStudents().add(s2) ;

c1.getAllStudents().add(s6) ;

s1.getAllCourses().add(c1) ;

s2.getAllCourses().add(c1) ;

s6.getAllCourses().add(c1) ;

// 第二门课程有六个学生参加

c2.getAllStudents().add(s1) ;

c2.getAllStudents().add(s2) ;

c2.getAllStudents().add(s3) ;

c2.getAllStudents().add(s4) ;

c2.getAllStudents().add(s5) ;

c2.getAllStudents().add(s6) ;

s1.getAllCourses().add(c2) ;

s2.getAllCourses().add(c2) ;

s3.getAllCourses().add(c2) ;

s4.getAllCourses().add(c2) ;

s5.getAllCourses().add(c2) ;

s6.getAllCourses().add(c2) ;

// 输出一门课程的信息,观察一门课程有多少个学生参加\

System.out.println(c1) ;

Iterator iter1 = c1.getAllStudents().iterator() ;

while(iter1.hasNext()){

Student s = iter1.next() ;

System.out.println("\t|- " + s) ;

}

// 通过学生找到学生参加的课程

System.out.println(s6) ;

Iterator iter2 = s6.getAllCourses().iterator() ;

while(iter2.hasNext()){

Course c = iter2.next() ;

System.out.println("\t|- " + c) ;

}

}

};

相关文章

JAVA教程全集-电子版(中)(java教程电子书下载)

第4章 面向对象的程序设计基础如前所述,Java语言是一种纯面向对象的编程语言,面向对象的程序设计是以类为基础的。从本章开始,我们将从类入手,详细介绍面向对象程序设计的基本思想和方法。本章将简要介绍面...

这些Java基础知识,诸佬们都还记得嘛(学习,复习,面试均可)

方法重载和方法重写的区别方法重写重写体现在继承关系上。 在Java中,子类继承父类,子类就会具备父类所以的特征,以及父类的方法和变量比如动物类有“叫”的方法,小狗小猫分别继承了动物类,重写方法时就可以...

三石说:java基础 类与对象(java的类和对象怎么理解)

类:类是封装对象的行为和属性的载体,具有相同属行和行为的一类实体。类中包含方法和属性。类中的构造方法:1.构造方法没有返回值2.名称与类名相同,在构造方法中可以为成员变量赋值,也就是初始化成员变量,若...

自学Java6(保姆级教学)——基本数据类型的转换

在上一期的文章中,我们认识了Java的几种运算符,先来简单回顾一下Java共有几类运算符:1.算数运算符:+,-,*,/(加减乘除),加上一个%(取余)2.赋值运算符:=3.关系运算符:˃,˂,==,...

Java|剖析类内的五类成员:属性、方法、构造器、代码块、内部类

Java的哲学是一切皆类,全部代码都写在类内。Java是纯面向对象的编程语言,类是其基石。Java类有五类成员:class Person{ // ① 属性,或成员变量 String n...

125题面试经常问的Java基础面试题整理与答案

1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二...