开发知识整理----数组和集合框架(2011-06)

[size=large][b]一、数组[/b][/size]
Java数组也是一种对象,必须通过new语句来创建。数组可以存放基本类型数据或引用类型的数据。同一个数组中只能存放相同类型的数据。用new语句创建一个数组后,数组中的每个元素都会被自动赋予与其数据类型相同的默认值。如int:0、boolean:false、String:null。创建数组时必须指明数组长度,一旦创建,其长度就不能再改变。

冒泡排序算法复杂度:O(n^2)
二叉查找算法复杂度:O(log2 n) ----n的以2为底数的对数。

1.声明数组变量时不能指定数组长度:
int x[3];//编译出错
int x[] = new int[3];// 合法


2.创建多维数组时,必须按照从低到高的顺序创建每一维数组:
int [][][] b = int [2][][3];//非法
int [][][] b = int [2][3][];//合法


String[][] rooms = new String[3][];
rooms[0]=new String[]{"tom","mike","jack","null"};
rooms[1]=new String[]{"mary","yao","null"};
rooms[2]=new String[]{"null","zhen","null","null"};
//等价于
String[][] rooms = {{"tom","mike","jack","null"},
{"mary","yao","null"},
{"null","zhen","null","null"}};



[size=large][b]二、Java集合[/b][/size]

在创建java数组时,必须指明数组的长度,数组一旦创建,其长度就不能被改变。但是在许多场合,我们的一组数据长度不是固定的,为此,JDK类库提供了java集合类供我们使用。(java.util包下)。与java数组不同,java集合中不能存放基本数据类型的数据,而只能存放对象的引用。

[b](一)java集合主要分为3类:[/b]

◆Set(集):集合中的对象不按特定方式排序,并且没有重复的对象。它的有些实现类能对集合中的对象按照特定方式排序。与数学中的集合概念很相近。

◆List(列表):集合中的对象按照索引位置排序,可以有重复的对象,允许按照对象在集合中的索引位置检索对象。List与数组有些相似。

◆Map(映射):集合中的每一个元素包含一对(键对象->值对象),集合中没有重复键对象,可以有重复的值对象。它的有些实现类能对集合中的键对象进行排序。


[b](二)java主要集合类的类框图[/b]

[img]http://dl.iteye.com/upload/attachment/494433/e43f5966-1290-384f-a60c-a64a4b1b9083.jpg[/img]

[b](三)Collection和Itetator接口[/b]

Collection接口中申明了(Set和List)的通用方法:详见JDK文档
boolean add(Object o) 向集合中加入一个对象的引用;

boolean remove(Object o) 从集合中删除一个对象的引用;
Iterator iterator() 返回一个Iterator对象,可用来遍历集合中的元素;

Object[] toArray() 返回一个数组,该数组包含集合中的所有元素; 注:Set接口和List接口都继承自Collection接口,所以它们实现类的对象都拥有上述的方法。而Map接口没有继承Collection接口,所以它的实现类对象没有上述方法。

●重点方法讲解:
Iterator iterator() 和 Object[] toArray() 作用均为获得集合中的所有元素。前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组。
Iterator接口隐藏了底层集合的数据结构,向客户程序提供了遍历各种类型集合的统一接口,它拥有3个方法:
1. boolean hasNext(): 判断集合中的元素是否遍历完毕,如果没有,则返回 true。
2. E next():返回下一个元素。
3. void remove(): 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

[b](四) Set(集)[/b]

Set接口主要实现类:HashSet 和 TreeSet。
HashSet :按照哈希算法存取集合中的对象,存取速度比较快。有一个主要的子类LinkedHashSet,该子类还实现了链表的数据结构,链表的数据结构能提高插入和删除元素的性能。
TreeSet:实现了SortedSet接口,具有排序功能,支持自然排序和客户化排序。

★专题:object类hashCode() 和 equals():

一个类重新实现了equals(),必须重写hashcode();例如:HashSet类是按照哈希算法来存取集合中的对象,具有很好的存取和查找性能。当向集合中加入一个对象时,HashSet会调用对象的hashCode方法来获得哈希码,然后根据这个哈希码计算出对象在集合中的存放位置。

在Object类中定义了hashCode()和equals()方法,Object类的equals()方法按照内存地址比较对象是否相等,因此如果 object1.equals(object2)为true,则表明object1变量和object2变量实际上引用同一个对象,那么object1和 object2的哈希码也肯定相同。

当TreeSet向集合中加入一个对象时,会把它插入到有序的对象序列中,那么TreeSet是如何对对象进行排序的呢?[b]TreeSet支持两种排序方式:自然排序和客户化排序,在默认情况下TreeSet采用自然排序方式。[/b]

[b]1.自然排序
[/b]
在JDK类库中,有一部分类实现了Comparable接口,如Integer,Double和String等。Comparable接口中有一个comparaTo(Object o)方法,它返回整数类型。对于表达式x.comparaTo(y),如果返回值=0,表示相等;>0,表示x>y;<0,表示x<y;

TreeSet调用对象的comparaTo()方法对象比较集合中对象的大小,然后进行升序排列,这种排序方式称为自然排序。

[color=red]使用自然排序时,只能向TreeSet集合中加入同类型的对象,并且这些对象的类必须实现了Comparable接口。(否则都会抛出ClassCastException异常)[/color]示例2

Set<Integer> set=new TreeSet<Integer>();
set.add(new Integer(8));
set.add(new String("9")); //抛出ClassCastException异常;在String类comparaTo(Object o)方法中,首先对参数O进行类型转化:String s=(String)o;若果o实际引用的不是String类型的对象,就会抛出该异常;


[b]2.客户化排序(常用)
[/b]
java.util.Comparator<Type>接口提供具体的排序方式,<Type>指定被比较的对象的类型,Comparator有个compare(Type x,Type y)方法,用于比较两个对象的大小。当compare(x,y)的返回值>0时,表示x>y;<0时,x<y;=0时,x=y;

如果希望TreeSet按照Customer对象的name属性进行降序排列,可以先创建一个实现Comparator接口的类CustomerComparator,实现compare(Type x,Type y)方法.在构造TreeSet的实例时,调用了它的TreeSet(Comparator comparator)构造方法,如:

Set<Customer> set=new TreeSet<Customer>(new CustomerComparator);

当TreeSet向集合中加入Customer对象时,会调用CustomerComparator类的compare()方法进行排序。

[b](五) List(列表)[/b]

List接口主要实现类:ArrayList 和 LinkedList 以及 Vector(不提倡使用,被前面2个替代)。
ArrayList:代表长度可变的数组。允许对元素进行快速的随机访问,但是向ArrayList中插入与删除元素的速度较慢。
LinkedList:在实现中采用了链表数据结构。对顺序访问进行了优化,插入数据较快,随机访问相对较慢。随机访问是指检索位于特定索引位置的元素。
补充:List只能对集合中的对象按索引位置排序,如果希望对List中的对象按其他特定的方式排序,可以借助Comparator接口和 Collections类。Collections类是JAVA集合类库中的辅助类,它提供了操纵集合的各种静态方法,其中Sort()方法用于对 List中的对象进行排序。

◆Sort(List list): 对List中的对象进行自然排序。

◆Sort(List list,Comparator comparator): 对List中的对象进行客户化排序,comparator参数指定了排序方式。

[b]补充:[/b]java.util.Arrays类的asList()方法能够把一个Java数组包装为一个List对象,这个List对象代表固定长度的数组。所有对List对象的操纵都会被作用到底层的Java数组。

[b](六) Map(映射)[/b]

重要方法:
(a)Map.entrySet() 返回此映射中包含的映射关系的 Set 视图。Map的entrySet()方法返回一个Set集合,在这个集合中存放了Map.Entry类型的元素,每个Map.Entry对象代表Map中的一对键值。
(b)Map的keySet()方法返回集合中所有键对象的集合。

Map接口主要实现类:HashMap, Hashtable(已经被HashMap替代) 和 TreeMap。
HashMap:也是按照哈希算法来存取键对象,所以和HashSet一样,要求当两个键对象通过equals()方法比较为true时,这两个键对象的hashCode()方法返回的哈希码也一样。
TreeMap:实现了SortedMap接口,具有排序功能,支持自然排序和客户化排序。如果希望TreeMap对键对象进行客户化排序,就调用它的另一个构造方法TreeMap(Comparator comparator),与TreeSet类似。

(七)HashSet和HashMap的负载因子

HashSet和HashMap都采用哈希算法来存取元素。哈希表中的每一个位置称为桶(bucket)。当发生哈希冲突时,在桶中以链表的形式存放多个元素。
[b]负载因子(load factor):[/b]元素个数/桶数量,负载因子为0时表示空的哈希表。0.5表示半满。轻负载的哈希表具有冲突少、适于插入、查找的优点(但是用Iterator遍历元素较慢)。
HashSet和HashMap允许用户指定负载因子,当哈希表当前负载超过指定负载时,表容量(即桶的数量)成倍增加,[color=red]且重新分配原有元素的位置。[/color]

默认负载因子为0.75,这个默认值很好的权衡了空间和时间的成本。如果负载因子较高,虽然可以减少内存空间需求,但会增加查找数据的时间开销,而查找是最频繁的操作,HashMap的get()和put()都涉及到查询操作,因此负载因子不宜过高。

(八)集合的编译时类型检查(JDK1.5引入泛型)
JDK1.5中引入泛型概览,它有助于把ClassCaseException运行时异常转为编译时类型不匹配错误。
Set<String> set; //指定set中只能存String对象
Set<? extends Object> set;//指定泛型上限,表示接收Object类型及其子类型
Set<? super String> set;//指定泛型下限,表示接收String类型及其父类型



(九)Collections辅助类
对于Java集合,JDK提供一个实用类java.util.Collections,它一部分方法专门用于操作List类型集合,一部分方法专门用于操作所有Collections类型或Map类型集合。

在JDK1.2以后版本的Java集合框架中,Set、List和Map的实现类(如HashSet、ArrayList、HashMap等)都没有采取同步机制。单线程中可以提高操作集合效率,JVM不必因为管理同步锁而产生额外开销,但多线程可能引起并发冲突。解决方法:
(a)在程序中可能导致并发问题的代码块进行同步;
(b)利用Collections的synchronizedXXX()方法获得原始集合的同步版本。
Collection synchronizedCollections = Collections.synchronizedCollection(originalCollection);

(c)如果集合只包含单个元素并不允许被修改,可用Collections的singleXXX()方法来构造这样的集合,这可以避免集合被线程错误的修改。
(d)如果集合的元素不允许被修改,可用Collections的unmodifiableXXX()方法来生成原始的集合视图,让线程只访问集合的视图,这也可避免集合被线程错误修改,而且由于不采用同步措施,可以提高并发性能。

[b](十)小结[/b]

(a)HashSet和HashMap具有较好的性能,是Set和Map首选实现类,只有在需要排序的场合,才考虑用TreeSet和TreeMap。
(b)LinkedList和ArrayList各有优劣,如果经常对集合进行插入和删除操作,可选用LinkedList,如果经常随机访问元素,那么可以用ArrayList。
(c)Java数组随机访问和迭代操作性能最好、LinkedList的插入和删除操作性能最好、ArrayList的随机访问操作性能也较高、Vector各方面性能都不突出,属于历史集合类,不提倡使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值