为什么要使用集合类
|
Java集合类
总的说来,Java API中所用的集合类,都是实现了Collection接口,他的一个类继承结构如下:
Collection<--List<--Vector
Collection<--List<--ArrayList
Collection<--List<--LinkedList
Collection<--Set<--HashSet
Collection<--Set<--HashSet<--LinkedHashSet
Collection<--Set<--SortedSet<--TreeSet
首先看下面这张表,本文即通过它展开相关内容。
|
Implementations |
|||||
Hash Table |
Resizable Array |
Balanced Tree |
Linked List |
Hash Table + LinkedList |
||
Interfaces |
Set |
HashSet |
|
TreeSet |
|
LinkedHashSet |
List |
|
ArrayList |
|
LinkedList |
|
|
Map |
HashMap |
|
TreeMap |
|
LinkedHashMap |
图1
Java集合类的种类
注意图1第二列,Java在设计集合结构时,把集合划成3类:第一种Set,普通的无序集;第 二种List,偏序集;第三种Map,有序对的集合。其中Set和List都继承自Collection接口,Map没有从Collection继承。这 样做也是没办法的事,因为Map并不是一个通常意义的集合,它的元素是一个key-value-pair,而Collection根本就不是Map,它还 没有key的概念。虽然Collection和Map彼此没有继承关系,但它们有大量同名的方法。值得注意的是,Map提供了keySet()和 values()两个方法,分别返回一个key的集合和值的集合。
示例1:通过对一个HashSet对象和一个ArrayList对象中元素使用跌代器可以显示Set与List中元素之间的顺序关系:Set中元素是无序的,List不是。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class ElementOrder ...{
public static void main(String[] args) ...{
Iterator it = null;
Set ht = new HashSet();
ht.add("htA");
ht.add("htB");
ht.add("htC");
ht.add("htD");
it = ht.iterator();
while (it.hasNext()) ...{
System.out.println(it.next());
}
List al = new ArrayList();
al.add("alA");
al.add("alB");
al.add("alC");
al.add("adD");
it = al.iterator();
while (it.hasNext()) ...{
System.out.println(it.next());
}
}
}
示例2:Map类型的集合对象通过keySet()和values()两个方法,分别返回一个key的集合(Set类型)和值的集合(Collection类型)。
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TestMap ...{
public static void main(String[] args) ...{
Iterator it = null;
Map tm = new HashMap();
tm.put("a", new Integer(1));
tm.put("b", new Integer(2));
tm.put("c", new Integer(3));
Set tk = tm.keySet();
it = tk.iterator();
while (it.hasNext()) ...{
System.out.println(it.next());
}
Collection tv = tm.values();
it = tv.iterator();
while (it.hasNext()) ...{
System.out.println(it.next());
}
}
}
Java集合类基于的常见数据结构
注意到图1 的第二行,是Java集合类基于的常见数据结构,它是集合对象中元素的组织方式。不同数据结构的类都有一些特定操作,参见示例。
示例3 List的一些排序操作。来自TheJava Developers Almanac 1.4
// Create a list
String[] strArray = new String[] ...{"z", "a", "C"};
List list = Arrays.asList(strArray);
// Sort
Collections.sort(list); // C, a, z
// Case-insensitive sort
Collections.sort(list, String.CASE_INSENSITIVE_ORDER); // a, C, z
// Reverse-order sort
Collections.sort(list, Collections.reverseOrder()); // z, a, C
// Case-insensitive reverse-order sort
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
Collections.reverse(list); // z, C, a
区别与联系
图1种各类的区别和联系很明显:同行同集合类性,同列同数据结构。
操作
根据Java集合框架的体系,不同的集合类在拥有父类型的操作时由于本身的集合类型和数据结构类型的不同,都有其特有的方法。兄弟类之间有同名的方法也可能因为同样的原因有不同的实现,这正好体现了OO的多态性。
其他
不可忽视的是java.util.Collections提供很多操作集合对象的静态方法。集合在Java还有其他非官方实现形式,如开源的Trove等。值得一提的是,示例1中Set ht = new HashSet();的定义方式体现了DIP(Dependence InversionPrinciple,依赖倒转原则)。
集合中存放的是对象的引用,而非对象本身 ,出于表达上的便利,简称为"集合中的对象".
Set(集):集合中的对象不按特定方式排列,并且没有重复对象,它的有些实现类能对集合中的对象按特定方式排列.
set接口主要有两个实现类HashSet和TreeSet,HashSet类按照哈希算法来存取集合中的对象,存取速度比较快,HashSet类还有一个子类LinkedHashSet类,不仅
实现了哈希算法,而且实现了链表数据结构,TreeSet类实现了SortedSet接口,具有排序功能.
那么,当一个新的对象加入到Set集合中,Set的add()方法是如何判断这个对象是否已经存在于集合中的呢?
boolean isExists=false;
Iterator it=set.iterator();
while(it.hasNext())
{
ObjectoldObject=it.next();
if(newObject.equals(oldObject))
{
isExists=true;
break;
}
}
可见,Set采用对象的equals()方法比较两个对象是否相等,而不是采用"=="比较运算符,以下程序代码尽管两次调用了Set的add()方法,
实际上只加入了一个对象:
Set set=new HashSet();
String s1=new String("hello");
String s2=new String("hello");
set.add(s1);
set.add(s2);
虽然变量s1和s2实际上引用的是两个内存地址不同的字符串对象,但是由于s2.equals(s1)的比较结果为true,因此Set认为他们是相等的对象,当第二次调用
Set的add()方法时,add()方法不会把s2引用的字符串对象加入到集合中.
HashSet类
按照哈希算法来存取集合中的对象,具有很好的存取性能,当HashSet向集合中加入一个对象时,会调用对象的hashCode()方法获得哈希码,然后根据这个哈希码
进一步计算出对象在集合中的存放位置.
在Object类中定义了hashCode()和equals()方法,Object类的euqals()方法按照内存地址比较对象是否相等,因此如果object1.equals(object2)为true,
表明object1
变量和object2变量十九上引用同一个对象.那么object1和object2的哈希码也应该相同.
***如果用户定义的类覆盖了Object类的equals()方法,但是没有覆盖Object类的hashCode()方法,就会导致当object1.equals(object2)为true时,而object1和object2的
哈希码不一定一样,这样使HashSet无法正常工作.
TreeSet类:
实现了SortedSet接口,能够对集合中的对象进行排序.
如:
Set set=new TreeSet();
set.add(new Integer(7));
set.add(new Integer(9));
set.add(new Integer(8));
Iterator it=set.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
输出结果为:6 7 8
当TreeSet向集合中加入一个对象时,会把它插入到有序的对象序列中,那么TreeSet是如何对对象进行排序的捏?TreeSet支持
两种排序方式:自然排序和客户化排序,默认情况下是自然排序.
在JDK中,有一部分类实现了Comparable接口,如Integer,Double和String等,Comparable接口有一个compareTo(Object o)方法,
它返回整数类型,对于表达式x.compareTo(y),如果返回值为0,表示x和y相等,如果返回值大于0,表示x大于y,如果小于0,表示x<y.
TreeSet调用对象的compareTo()方法比较集合中对象的大小,然后进行升序排序,这种方式称为自然排序.
客户化排序:
java.util.Comparator接口用于指定具体的排序方式,它有个compare(Objectobj1,Object obj2),用于比较两个对象的大小.
当表达式compare(x,y)的值大于0,表示x大于y,小于0,表示x小于y,等于0,表示x等于y,如果想让TreeSet进按照Customer对象的
name属性进行降序排列,可以先创建实现Comparator接口的类CustomerComparator,如:
import java.util.*;
public class CustomerComparator implementsComparator
{
public int compare(Object o1,Object o2)
{
Customer c1=(Custoemr)o1;
Customer c2=(Customer)o2;
if(c1.getName().compareTo(c2.getName())>0) return -1;
if(c1.getName().compareTo(c2.getName())<0) return 1;
return 0;
}
}
接下来在构造TreeSet的实例时,调用它的TreeSet(Comparator comparator)构造方法
Setset=new TreeSet(new CustomerComparator());
Customer c1=new Customer("TOM",15);
Customer c2=new Customer("JACK",20);
Customer c3=new Customer("MIKE",38);
set.add(c1);set.add(c2);set.add(c3);
Iterator it=set.iterator();
while(it.hasNext())
{Custoemr customer=(Customer)it.next();
&n
bsp; System.out.println(customer.getName()+"" +customer.getAge();)
}
当TreeSet向集合中加入Customer对象时,会调用CustomerComparator类的compare()方法进行排序,以上Tree按照
Custoemr对象的name属性进行降序排列,最后输出为:
TOM 15 MIKE38 JACK 16
List(列表):对象以线性方式存储,集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象.
实现类有LinkedList,ArrayList和Vector,LinkedList采用链表数据结构,而ArrayList代表大小可变的数组,Vector和
ArrayList比较相似,两者的区别在于Vecotr类的实现采用了同步机制,而ArrayList没有使用同步机制/
List按索引排列:
List list=new ArrayList();
list.add(new Integer(3));
list.add(new Integer(4));
list.add(new Integer(3));
list.add(new Integer(2));
List的get(int index)方法返回集合中由参数index指定的索引位置的对象,第一个加入到集合中的对象的索引位置为0,
for( int i=0,i<list.size;i++)
{System.out.println(list.get(i));}
输出结果为:3 4 3 2.
List只能对集合中的对象按索引位置排序,如果希望对List中的对象按其他特定方式排序,可以借助Comparator接口和Collections类.
Collections类是Java集合API中的辅助类,它提供了操纵集合的各种静态方法,
其中sort()方法用于对List中的对象进行排序:
sort(List list):对List中的对象进行自然排序.
sort(Listlist,Comparator comparator):对List中的对象进行客户化排序,comparator参数指定排序方式.
对以下List进行自然排序:
List list=newArrayList();
list.add(newInteger(3));
list.add(newInteger(4));
list.add(newInteger(3));
list.add(newInteger(2));
Collections.sort(list);
for(inti=0;i<list.size();i++)
{
System.out.println(list.get(i));
}
以上输出结果:2 3 3 4
Map(映射):集合中的每一个元素包含一对键对象和一对值对象,集合中没有重复的键对象,值对象可以重复,它的有写实现类能
对集合中的键对象进行排序.
Map map=new HashMap();
map.put("1","Mon");
map.put("1",Monday);
map.put("2","monday");
由于第一次和第二次加入到Map中的键对象都是1,所以第一次加入的值对象将被覆盖,而第二个和第三个的值对象虽然相同,但是
键对象不一样,所以分配了不同的地址空间,所以不会覆盖,也就是说一共有两个元素在Map集合中.
Map有两种比较常用的实现:HashMap和TreeMap.Hashmap按照哈希算法来存取键对象,有很好的存取能力,为了保证HashMap能正常工作,
和HashSet一样,要求当两个键对象通过equals()方法比较为true时,这两个键对象的hashCode()方法返回的哈希码也一样.
TreeMap实现了SortedMap接口,能对键对象进行排序,和TreeSet一样,TreeMap也支持自然排序和客户化排序两种方式,以下程序中的TreeMap
会对四个字符串类型的键对象"1","3","4","2"进行自然排序:
Map map=new TreeMap();
map.put("1","Monday");
map.put("3","Wendsday");
map.put("4","Thursday");
map.put("2",
"Tuesday");
//返回集合中所有键对象的集合
Set keys=map.keySet();
Iterator it=keys.iterator();
while(it.hasNext)
{String key=(String)it.next();
//根据键对象得到值对象
String value=(String)map.get(key);
System.out.println(key+"" +value);
}
以上输出结果为:1 Monday 2 Wendsday 3 Thursday 4Tuesday
如果希望TreeMap进行客户化排序,可以调用它的另一个构造方法TreeMap(Comparatorcomparator),参数comparator指定具体的排序方式.
相关推荐
Java集合类框架如图所示Java 8集合类框架:Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:1. Collection -- 一个独立
java集合类框架图
Java 集合类详解 Java 集合类是 Java 语言中的一种基本数据结构,用于存储和操作大量数据。集合类可以分为三大类:Collection、List 和 Set。 Collection 是集合框架中的根接口,提供了基本的集合操作,如 add、...
本文将结合上述 Bloch 关于线程安全等级的定义,对 Java 集合框架中的集合类进行线程安全性分析,并指出各个集合类在现实的编程环境中需要注意的并发编程的陷阱;同时对集合框架中通用算法对线程安全性的影响进行...
Java集合类框架是Java标准库的一个重要组成部分,主要用于存储和处理数据集合。这些集合类被定义在`java.util`包中,为开发者提供了灵活的数据结构来实现各种应用程序的需求。由于集合类数量众多且功能各异,初学者...
Java集合框架是Java编程语言中的一个核心组成部分,它为存储、管理和操作对象提供了一套统一的接口和类。本文将深入解析Java集合框架的各个方面,包括Collection、List、Set和Map,以及它们的相关实现和使用原理。 ...
### Java集合框架总结 #### 一、Java集合框架概述 Java集合框架是Java标准库的一部分,它提供了一系列的接口和类来存储和操作各种类型的对象集合。这些接口和类遵循一致的设计模式,使得开发人员可以方便地管理和...
xmind格式的Java集合框架学习导图,包括Collection接口/Map接口以及具体实现类。 同样包含大厂面试题,也在导图中有所体现。 能学到什么: 更加成体系的知识框架,更加全面的、系统的知识。 思维导图: 思维导图具有...
此外,还有五个抽象类以及多个实现类,它们共同构成了Java集合框架的基础。 #### 二、核心接口介绍 1. **`Collection`接口**: - 这是最基本的接口,所有其他集合接口都是它的子类。它代表了一组对象,其中可能...
Java-集合类框架参考图
集合是将多个元素组成一个单元的...Java集合框架,为我们提供了一套性能优良、使用方便的接口和类,我们不必再重新发明轮子,只需学会如何使用它们,就可以处理实际应用中出现的问题了Java集合框架位于java.util包中
### Java集合排序及Java集合类详解 #### 一、集合框架概述 集合框架是Java编程语言的核心组件之一,用于组织和操作数据集。Java集合框架提供了多种数据结构,包括列表(List)、集(Set)和映射(Map),这些数据结构...
Java集合List集合Set集合Map集合Collection和collections工具类的框架图
本篇将详细探讨Java集合框架的基础知识,包括核心接口、类的层级结构以及Java 5引入的泛型特性。 首先,让我们了解一下`java.lang.Class`。`Class`类在Java中扮演着特殊的角色,它不仅是一个普通类,而且是用于获取...
Java集合框架常见面试题 剖析⾯试最常⻅问题之 Java 集合框架 包含以下几个模块: 1、集合概述 2、Collection子接口之List 3、Collection子接口之Set 4、Map接口 5、Collection工具类 6、其他重要问题
Java 集合排序及java 集合类详解 Java 集合排序及java 集合类详解,Java里面最重要、最常用也就是集合那部分了,能够用好集合和理解好集合对于做Java程序的开发拥有无比的好处。本教程详细解释了关于Java中的集合是...
Java集合框架是Java编程语言中一个非常重要的组成部分,它提供了一组高效的数据结构和操作这些数据结构的方法。泛型则是Java在J2SE 5.0版本引入的一个特性,极大地提高了代码的类型安全性和可读性。下面我们将深入...