西塘古镇,Java集合框架概述,田子坊

一、调集结构图

简化图:

阐明:关于以上的结构图有如下几点阐明

  1. 一切调集类都坐落java.util包下。Java的调集类首要由两个接口派生星游文娱登录而出:Collection和Map,Collection和Map是Java调集结构的根接口,这两个接口又包括了一些子接口或完成类。
  2. 调集徐少强接口:6个接口(短虚线标明),标明不同调集类型,是调集结构的根底。
  3. 笼统类:5个笼统类(长虚线标明),对调集接口的部分完成。可扩展为自界说调集类。
  4. 完成类:8个完成类(实线标明),对接口的详细完成。
  5. Collection 接口是一组答应重复的目标。
  6. Set 接口承继 Collection,调集元素不重复。
  7. List 接口承继 Collection,答应重复,保护元素刺进次第。
  8. Map接口是键-值目标,与Collection接口没有什么联系。
  9. Set、List和Map能够看做调集的三大类:
  • List调集是有序调集,调集中的元素能够重复,拜访调集中的元素能够依据元素的索引来拜访。
  • Set调集是无序调集,调集中的元素不能够重复,拜访调集中的元素只能依据元素本身来拜访(也是调集里元素不答应重复的原因)。
  • Map调集中保存Key-value对办法的元素,拜访时只能依据每项元素的key来拜访其value。

二、全体剖析

大致阐明

看上面的结构图,先捉住它的骨干,即Collection和Map。

  1. Collection是一个接口,是高度笼统出来的调集,它包括了调集的根本操作和特色。Collection包括了List和Set两大分支。
  • List是一个有序的行列,每一个元素都有它的索引。榜首个元素的索引值是0。List的完成类有LinkedList, ArrayList, Vector, Stack。
  • Set是一个不答应有重复元素的调集。Set的完成类有HastSet和TreeSet。HashSet依赖于HashMap,它实践上是经过HashMap完成的;TreeSet依赖于TreeMap,它实践上是经过TreeMap完成的。
  1. Map是一个映射接口,即key-value键值对。Map中的每一个元素包括“一个key”和“key对应的value”。AbstractMap是个笼统类,它完成了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是承继于AbstractMap。Hashtable尽管承继于Dictionary,但它完成了Map接口。
  2. 接下来,再看Iterator。它是遍历调集的东西,即咱们一般经过Iterator迭代器来遍历调集。咱们说Collection依赖于Iterator,是由于Collection的完成类都要完成iterator()函数,回来一个Iterator目标。ListIterator是专门为遍历List而存在的。
  3. 再看Enumeration,它是JDK 1.0引进的笼统类。效果和Iterator相同,也是遍历调集;可是Enumeration的功用要比Iterator少。在上面的框图中,Enumeration只能在Hashtable, Vector, Stack中运用。
  4. 最终,看Arrays和Collections。它们是操作数组、调集的两个东西类。
有了上面的全体结构之后,咱们接下来对每个类别离进行剖析。

三、Collection接口

Collection接口是处理目标调集的根接口,其间界说了许多对元素进行操作的办法。Collection接口有两个首要的子接口List和Set,留意Map不是Collection的子接口,这个要紧记

Collection接口中的办法如下:

其间,有几个比较常用的办法,比方办法add()增加一个元素到调集中,addAll()将指定调集中的一切元素增加到调集中,contains()办法检测调集中是否包括指定的元素,toArray()办法回来一个标明调集的数组。

别的,Collection中有一个iterator()函数,它的效果是回来一个Iterator接口。一般,咱们经过Iterator迭代器来遍历调集。ListIterator是List接口所特有的,在List接口中,经过ListIterator()回来一个ListIterator目标。

Collection接口有两个常用的子接口,下面详细介绍。

1.List接口

List调集代表一个有序调集,调集中每个元素都有其对应的次第索引。List调集答应运用重复元素,能够经过索引来拜访指定方位的调集元素

List接口承继于Collection接口,它能够界说一个答应重复的有序调集。由于List中的元素是有序的,所以咱们能够经过运用索引(元素在List中的方位,类似于数组下标)来拜访List中的元素,这类似于Java的数组。

List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的刺进次第来保护元素次第。用户能够对列表中每个元素的刺进方位进行精确地操控,一起能够依据元素的整数索引(在列表中的方位)拜访元素,并查找列表中的元素。完成List接口的调集首要有:ArrayList、LinkedList、Vector、Stack。

(1)ArrayList

ArrayList是一个动态数组,也是咱们最常用的调集。它答应任何契合规矩的元素刺进乃至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的巨细。跟着容器中的元素不断增加,容器的巨细也会跟着增加。在每次向容器中增加元素的一起都会进行容量检查,当快溢出时,就会进行扩容操作。所以假如向海清废了咱们清晰所刺进元素的多少,最好指定一个初始容量值,防止过多的进行扩容操作而浪费时刻、功率。

size、isEmpty、get、set、iterator和 listIterator操作都以固定时刻运转。add 操作以分摊的固定时刻运转,也便是说,增加 n 个元素需求 O(n) 时刻(由于要考虑到扩容,所以这不只是增加元素会带来分摊固定时刻开支那样简略)。

ArrayList擅长于随机拜访。一起ArrayList对错同步的。

(2)LinkedList

相同完成List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。所以它除了有ArrayList的根本操作办法外还额定供给了get,remove,insert办法在LinkedList的首部或尾部。

由于完成的办法不同,LinkedList不能随机拜访,它一切的操作都是要依照两层链表的需求履行。在列表中索引的操作将从最初或结束遍历列表(从接近指定索引的一端)。这样做的优点便是能够经过较低的价值在List中进行刺进和删去操作。

与ArrayList相同,LinkedList也对错同步的。假如多个线程一起拜访一个List,则有必要自己完成拜访同步。一种解决办法是在创立List时结构一个同步的Li西塘古镇,Java调集结构概述,田子坊st血压高的原因:

List list = Collections.synchronizedList(new LinkedList(...));

(3)Vector

与西塘古镇,Java调集结构概述,田子坊ArrayList类似,可是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList简直相同。

(4)Stac重生之畅游时空k

Stack承继自Vector,完成一个后进先出的仓库。Stack供给5个额定的办法使得Vector得以被当作仓库运用。根本的push和pop 办法,还有peek办法得到栈顶的元素,empty办法测验仓库是否为空,search办法检测一个元素在仓库中的方位。Stack刚创立后是空栈。

2.Set接口

Set是一种不包括重复元素的Collection。它坚持它自己的内部排序,所以随机拜访没有任何含义。与List相同,它相同答应null的存在可是仅有一个。由于Set接口的特殊性,一切传入Set调集中的元素都有必要不同,一起要留意任何可变目标,假如在对调集中元素进行操作时,导致e1.equals(e2)==true,则必定会发生某些问题。Set接口有三个详细完成类,别离是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。

Set是一种不包括重复的元素的Collection,无序,即恣意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素

需求留意的是:尽管Set中元素没有次第,可是元素在set中的方位是由该元素的HashCode决议的,其详细方位其实是固定的。

此外需求阐明一点,在set接口中的不重复是有特殊要求的。

举一个比如:目标A和目标B,本来是不同的两个目标,正常状况下它们是能够放入到Set里边的,可是假如目标A和B的都重写了hashcode和equals办法,而且重写后的hashcode和equals办法是相同的话。那么A和B是不能一起放入到Set调集中去的,也便是Set调集中的去重和hashcode与equals办法直接相关。

为了更好地了解,请看下面的比如:

public class Test{

public static void main(String[] args) {

Set set=new HashSet();

set.add("Hello");

set.add("world");

set.add("Hello");

System.out.println("调集的尺度为:"+set.size());

System.out.println("调集中的元素为:"+set.toString());

}

}

运转成果:

调集的尺度为:2

调集中的元素为:[world, Hello]

剖析:由于String类中重写了hashcode和equals办法,用来比较指向的字符串目标所存储的字符串是否持平。所以这儿的第二个Hello是加不进去的。

再看一个比如:

public class TestSet {

public static void main(String[] args){

Set books = new HashSet();

//增加一个字符串目标

books.add(new String("Struts2威望攻略"));

//再次增加一个字符串目标,

//由于两个字符串目标经过equals办法比较持平,所以增加失利,回来false

boolean result = books.add(new String("Struts2威望攻略"));

System.out.println(result);

//下面输出看到调集只需一个元素

System.out.println(books);

}

}

运转成果:

false

[Struts2威望攻略]

阐明:程序中,book调集两次增加的字符串目标显着不是一个目标(程序经过new关键字来创立字符串目标),当运用==运算符判别回来false,运用equals办法比较回来true,所以不能增加到Set调集中,最终只能输出一个元素。

(1)HashSet

HashSet 是一个没有重复元素的调集。它是由HashMap完成的,不保证元素的次第(这儿所说的没有次第是指:元素刺进的次第与输出的次第不一致),而且HashSet答应运用null 元素。HashSet对错同步的,假如多个线程一起拜访一个哈希set,而其间至少一个线程修正了该set,那么它有必要坚持外部同步。 HashSet按Hash算法来存储调集的元素,因而具有很好的存取和查找功用

HashSet的完成办法大致如下,经过一个HashMap存储元素,元素是寄存在HashMap的Key中,而Value一致运用一个Object目标。

HashSet运用和了解中简略呈现的误区:

  • HashSet中寄存null值。HashSet中是答应存入null值的,可是在HashSet中只是能够存入一个null值。
  • HashSet中存储元素的方位是固定的。HashSet中存储的元素的是无序的,这个没什么好说的,可是由于HashSet底层是依据Hash算法完成的,运用了hashcode,所以HashSet中相应的元素的方位是固定的。
  • 有必要当心操作可变目标(Mutable Object)。假如一个Set中的可变元素改变了本身状况导致Object.equals(Object)=true将导致一些问题。

(2)LinkedHashSet

LinkedHashSet承继自HashSet,其底层是依据LinkedHashMap来完成的,有序,非同步。LinkedHashSet调集相同是依据元素的hashCode值来决议元素的存储方位,可是西塘古镇,Java调集结构概述,田子坊它一起运用链表保护元素的次第。这样使得元素看起来像是以刺进次第保存的,也便是说,当遍历该调集时分,LinkedHashSet将会以元素的增加次第拜访调集的元素。

(3)TreeSet

TreeSet是一个有序调集,其底层是依据TreeMap完成的,非线程安全。TreeSet能够保证调集元素处于排序状况。TreeSet支撑两种排序办法,天然排序和定制排序,其间天然排序为默许的排序办法。当咱们结构TreeSet时,若运用不带参数的结构函数,则TreeSet的运用天然比较器;若用户需求运用自界说的比较器,则需求运用带比较器的参数。

留意:TreeSet调集不是经过hashcode和equals函数来比较元素的.它是经过compare或许comparaeTo函数来判别元素是否持平.compare函数经过判别两个目标的id,相同的id判别为重复元素,不会被参加到调集中。

四、Map接口

Map与List、Set接口不同,它是由一系列键值对组成的调集,供给了key到Value的映射。一起它也没有承继Collection。在Map中它保证了key与value之间的一一对应联系。也便是说一个key对应一个value,所以它不能存在相同的key值,当然value值能够相同

1.HashMap

以哈希表数据结构完成,查找目标时经过哈希函数核算其方位,它是为快速查询而规划的,其内部界说了一个hash表数组(Entry[]西塘古镇,Java调集结构概述,田子坊 table),元素会经过哈希转化函数将元素的哈希地址转化成数组中寄存的索引,假如有抵触,则运用散列链表的办法将一切相同哈希地址的元素串起来,或许经过检查HashMap.Entry的源码它是一个单链表结构。

2.LinkedHashMap

LinkedHashMap是HashMap的一个子类,它保存刺进的次第,假如需求输出的次第和输入时的相同,那么就选用LinkedHashMap。

LinkedHashMap是Map接口的哈希表和链接列表完成,具有可预知的迭代次第。此完成供给一切可选的映射操作,并答应运用null值和null键。此类不保证映射的次第,特别是它不保证该次第恒久不变。

LinkedHashMap完成与HashMap的不同之处在于,后者保护着一个运转于一切条目的两层链接列表。此链接列表界说了迭代次第,该迭代次第能够是刺进次第或许是拜访次第。

依据链表中元素的次第能够分为:按刺进次第的链表,和按拜访次第(调用get办法)的链表。默许是按刺进次第排序,假如指定按拜访次第排序,那么调用get办法后,会将这次拜访的元素移至链表尾部,不断拜访能够构成按拜访次第排序的链表。

留意,此完成不是同步的。假如多个线程一起拜访链接的哈希映射,而其间至少一个线程从结构上修正了该映射,则它有必要坚持外部同步。由于LinkedHashMap需求保护元素的刺进次第,因而功用略低西塘古镇,Java调集结构概述,田子坊于HashMap的功用,但在ancient迭代拜访Map里的悉数元素时将有很好的功用,由于它以链表来保护内部次第。

3.TreeMap

TreeMap 是一个有序的key-value调集,非同步,依据红黑树(Red-Black tree)完成,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会依据key来对key-value键值对进行排序,其间排序办法也是分为两种,一种是天然排序,一种是定制排序,详细取决于运用的结构办法。

天然排序:TreeMap中一切的key有必要完成Comparable接口,而且一切的key都应该是同一个类的目标,不然会报ClassCastException反常。

定制排序:界说TreeMap时,创立一个comparator目标,该目标对一切的treeMap中一切的key值进行排序,选用定制排序的时分不需求TreeMap中一切的key有必要完成Comparable接口。

TreeMap判别两个元素持平的规范:两个key经过compareTo()办法回来0,则以为这两个key持平。

假如运用自界说的类来作为TreeMap中的key值,且想让TreeMap能够杰出的作业,则有必要重写自界说类中的equals()办法,TreeMap中判别持平的规范是:两个key经过equals()办法回来为true,而且经过compareTo()办法比较应该回来为0。


五、Iterator 与 ListIterator详解

1.Iterator

Iterator的界说如下:

public interface Iterator {}

Iterator是一个接口,它是调集的迭代器。调集能够经过Iterator去遍历调集中的元素。

  • Iterator供给的API接口如下:
  • boolean hasNext():判别调集里是否存在下一个元素。假如有,hasNext()办法回来 true。
  • Object next():回来调集里下一个元素。

void remove():删去调集里上一次next办法回来的元素。

运用示例:

public class IteratorExample {

public static void main(String[] args) {

ArrayList a = new ArrayList();

a.add("aaa");

a.add("bbb");

a.add("ccc");

System.out.println("Before iterate : " + a);

Iterator it = a.iterator();

while (it.hasNext()) {

String t = it.next();

if ("bbb".equals(t)) {

it.remove();

}

}

System.out.println("After iterate : " + a);

}

}

输出成果如下:

Before iterate : [aaa, bbb, ccc]

After iterate : [aaa, ccc]

留意

  • Iterator只能单向移动。
  • Iterator.remove()是仅有安全的办法来在迭代进程中修正调集;假如在迭代进程中以任何其它的办法修正了根本调集将会发生不知道的行为。而且每调用一次next()办法,remove()办法只能被调用一次,假如违背这个规矩将抛出一个反常。

2.ListIterator

ListIterator是一个功用愈加强壮的迭代器, 它承继于Iterator接口,只能用于各种List类型的拜访。能够经过调用listIterator()办法发生一个指向List开端处的ListIterator, 还能够调用listIterator(n)办法创立一个一开端就指向列表索引为n的元素处的ListIterator。

ListIterator接口界说如下:

public interface ListIterator extends Iterator {

boolean hasNext();

E next();

boolean hasPrevious();

E previous();

int nextIndex();

int previousIndex();

void remove();

void set(E e);

void add(E e);

}

由以上界说咱们能够推出ListIterator能够:

  • 双向移动(向前/向后遍历).
  • 发生相关于迭代器在列表中指向的当时方位的前一个和后一个元素的索引.
  • 能够运用set()办法替换它拜访过的最终一个元素.
  • 能够运用add()办法在next()办法回来的元素之前或previous()办法回来的元素之后刺进一个元素.

运用示例:

public class ListIteratorExample {

public static void main(String[] args) {

ArrayList a = new ArrayList();

a.add("aaa");

a.add("bbb");

a.add("ccc");

System.out.println("Before iterate : " + a);

ListIterator it = a.listIterator();

while (it.hasNext()) {

System.out.println(it.next() + ", " + it.previousIndex() + ", " + it.nextIndex());

}

while (it.hasPrevious()) {

System.out.print(it.previous() + " ");

}

System.out.println();

it = a.listIterator(1);

while (it.hasNext()) {

String t = it.next();

System.out.println(t);

if ("ccc".equals(t)) {

it.set("nnn");

} else {

it.add("kkk");

}

}

System.out.println("Afte倩女幽魂2r iterate : " + a);

}

}

输出成果如下:

Before iterate : [aaa, bbb, ccc]

aaa, 0, 1

bbb, 1, 2

ccc, 2, 3

ccc bbb aaa

bbb

ccc

After iterate : [aaa, bbb, kkk, nnn]


六、异同点

1.ArrayList和LinkedList

  • Array实在女友List是完成了依据动态数组的数据结构,LinkedList依据链表的数据结构。
  • 关于随机拜访get和set,Arra榜首yList肯定优于LinkedList,由于LinkedList要移动指针。
  • 关于新增和删去操作add和remove,LinedList比较占优势,由于ArrayList要移动数据。

这一点要看实践状况的。若只对单条数据刺进或删去,ArrayList的速度反而优于LinkedList。但若是批量随机的刺进删去数据,LinkedList的速度大大优于ArrayList. 由于ArrayList每刺进一条数据,要移动刺进点及之后的一切数据。

2.HashTable与HashMap

相同点

  • 都完成了Map、Cloneable、java.io.Serializable接口。
  • 都是存储"键值对(key-value)"的散列表,而且都是选用拉链法完成的。

不同点

  1. 前史原因:HashTable是依据陈腐的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个完成 。
  2. 同步性:HashTable是线程安全的,也便是说是同步的,而HashMap是线程序不安全的,不是同步的 。
  3. 对null值的处理:HashMap的key、value都可为null,HashTable的key、value都不可为null 。
  4. 基类不同:HashMap承继于AbstractMap,而Hashtable承继于Dictionary。
  • Dictionary是一个笼统类,它直接承继于Object类,没有完成任何接口。Dictionary类是JDK 1.0的引进的。尽管Dictionary也支撑“增加key-value键值对”、“获取value”、“获取巨细”等根本操作,但它的API函数比Map少;而且Dictionary一般是经过Enumeration(枚举类)去遍历,Map则是经过Iterator(迭代M器)去遍历。 可是由于Hashtable也完成了Map接口,所以,它即支撑Enumeration遍历,也支撑Iterator遍历。
  • AbstractMap是一个笼统类,它完成了Map接口的绝大部分API函数;为Map的详细完成类供给了极大的便当。它是JDK 1.2新增的类。
  1. 支撑的遍历品种不同:HashMap只支撑Iterator(迭代器)遍历。而Hashtable支撑Iterator(迭代器)和Enumeration(枚举器)两种办法遍历。

3.HashMap、Hashtable、LinkedHashMap和TreeMap比较

Hashmap 是一个最常用的Map,它依据键的HashCode 值存储数据,依据键能够直接获取它的值,具有很快的拜访速度。遍历时,获得数据的次第是彻底随机的。HashMap最多只答应一条记载的键为Null;答应多条记载的值为Null;HashMap不支撑线程的同步,即任一时刻能够有多个线程一起写HashMap;或许会导致数据的不一致。假如需求同步,能够用Collections的synchronizedMap办法使HashMap具有同步的才能。

Hashtable 与 HashMap类似,不同的是:它不答应记载的键或许值为空;它支撑线程的同步,即任一时刻属只需一个线程能写Hashtable,因而也导致了Hashtale在写入时会比较慢。

LinkedHashMap保存了记载的刺进次第,在用Iterator遍历LinkedHashMap时,先得到的记载肯定是先刺进的,也能够在结构时用带参数,依照运用次数排序。在遍历的时分会比HashMap慢,不过有种状况破例,当HashMap容量很大,实践数据较少时,遍历起来或许会比LinkedHashMap慢,由于LinkedHashMap的遍历速度只和实践数据有关,和容西塘古镇,Java调集结构概述,田子坊量无关,而HashMap的遍历速度和他的容量有关

假如需求输出的次第和输入的相同,那么用LinkedHashMap能够完成,它还能够按读取次第来摆放,像衔接池中能够运用。LinkedHashMap完成与HashM酒鬼酒ap的不同之处在于,后者保护着一个运转于一切条目的两层链表。此链接列表界说了迭代次第,该迭代次第能够是刺进次第或许是拜访次第。关于LinkedHashM轮胎排名ap而言,它承继与HashMap、底层运用哈希表与双向链表来保存一切元素。其根本操作与父类HashMap类似,它经过重写父类相关的办法,来完成自己的链接列表特性。

TreeMap完成SortMap接口,内部完成是红黑树。能够把它保存的记载依据键排序,默许是按键值的升序排序,也能够指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记载是排过序的。TreeMap不答应key的值为null。非同步的。

一般状况下,咱们用的最多的是HashMap,HashMap里边存入的键值对在取出的时分是随机的,它依据键的HashCode值存储数据,依据键能够直接获取它的值,具有很快的拜访速度。在Map 中刺进、删去和定位元素,HashMap 是最好的挑选。

TreeMap取出来的是排序后的键值对。但假如您要按天然次第或自界说次第遍历键,那么TreeMap会更好。

LinkedHashMap 是HashMap的一个子类,假如需求输出的次第和输入的相同,那么用LinkedHashMap能够完成,它还能够按读取次第来摆放,像衔接池中能够运用。

import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.TreeMap;

public class MapTest {

public static void main(String[] args) {

//HashMap

HashMap hashMap = new HashMap();

hashMap.put("4", "d");

hashMap.put("3", "c");超级无敌唱衰你

hashMap.put("2", "b");

hashMap.put("1", "a");

Iterator iteratorHashMap = hashMap.keySet().iterator();

System.out.println("HashMap-->");

while (iteratorHashMap.hasNext()){

Object key1 = iteratorHashMap.next();

System.out.println(key1 + "--" + hashMap.get(key1));

}

//LinkedHashMap

LinkedHashMap linkedHashMap = new LinkedHashMap();

linkedHashMap.put("4", "d");

linkedHashMap.put("3", "c");

linkedHashMap.put("2", "b");

linkedHashMap.put("1", "a");

Iterator iteratorLinkedHashMap = linkedHashMap.keySet().iterator();

System.out.println("LinkedHashMap-->");

while (iteratorLinkedHashMap.hasNext()){

Object key2 = iteratorLinkedHashMap.next();

System.out.println(key2 + "--" + linkedHashMap.get(key2));

}

//TreeMap

TreeMap treeMap = new TreeMap();

treeMap.pu梦到猫t("4", "d");

treeMap.put("3", "c");

treeMap.put("2", "b");

treeMap.put("1", "a");

Iterator iteratorTreeMap = treeMap.keySet().iterator();

System.out.println("TreeMap-->");

while (iteratorTreeMap.hasNext()){

Object key3 = iteratorTreeMap.next();

System.out.println(key3 + "--" + treeMap.get(key3));

}

}

}

输出成果:

HashMap-->

3--c

2--b

1--a

4--d

LinkedHashMap-->

4--d

3--c

2--b

1--a

TreeMap-->

1--a

2--b

3--c

4--d

4.HashSet、LinkedHashSet、TreeSet比较

Set接口

Set不答应包括相同的元素,假如企图把两个相同元素参加同一个调集中,add办法回来false。

Set判别两个目标相同不是运用==运算符,而是依据equals办法。也便是说,只需两个目标用equals办法比较回来true,Set就不会承受这两个目标。

HashSet

HashSet有以下特色:

  • 不能保证元素的摆放次第,次第有或许发生变化。
  • 不是同步的。
  • 调集元素能够是null,但只能放入一个null。

当向HashSet结合中存入一个元素时,HashSet会调用该目标的hashCode()办法来得到该目标的hashCode值,然后依据 hashCode值来决议该目标在HashSet中存储方位。简略的说,HashSet调集判别两个元素持平的规范是两个目标经过equals办法比较持平,而且两个目标的hashCode()办法回来值也持平

留意,假如要把一个目标放入HashSet中,重写该目标对应类的equals办法,也应该重写其hashCode()办法。其规矩是假如两个目标经过equals办法比较回来true时,其hashCode也应该相同。别的,目标中用作equals比较规范的特色,都应该用来核算 hashCode的值。

LinkedHashSet

LinkedHashSet调集相同是依据元素的hashCode值来决议元素的存储方位,可是它一起运用链表保护元素的次第。这样使得元素看起来像是以刺进次第保存的,也便是说,当遍历该调集时分,LinkedHashSet将会以元素的增加次第拜访调集的元素。

LinkedHashSet在迭代拜访Set中的悉数元素时,功用比HashSet好,可是刺进时功用略微差劲于HashSet

TreeSet类

TreeSet是SortedSet接口的仅有完成类,TreeSet能够保证调集元素处于排序状韩先楚态。TreeSet支撑两种排序办法,天然排序和定制排序,其间天然排序为默许的排序办法。向TreeSet中参加的应该是同一个类的目标。

TreeSet判别两个目标不持平的办法是两个目标经过equals办法回来false,或许经过CompareTo办法比较没有回来0

天然排序

天然排序运用要排序元素的CompareTo(Object obj)办法来比较元素之间巨细联系,然后将元素依照升序摆放。

Java供给了一个Comparable接口,该接口里上海黄金交易所今天金价界说了一个compareTo(Object obj)办法,该办法回来一个整数值,完成了该接口的目标就能够比较巨细。obj1.compareTo(obj2)办法假如回来0,则阐明被比较的两个目标持平,假如回来一个正数,则标明obj1大于obj2,假如是负数,则标明obj1小于obj2。假如咱们将两个目标的equals办法总是回来true,则这两个目标的compareTo办法回来应该回来0。

定制排序

天然排序是依据调集元素的巨细,以升序摆放,假如要定制排序,应该运用Comparator接口,完成int compare(T o1,T o2)办法。

package com.test;

import java.util.HashSet;

import java.util.LinkedHashSet;

import java.util.TreeSet;

/**

* @description 几个set的比较

* HashSet:哈希表是经过运用称为散列法的机制来存储信息的,元素并没有以某种特定次第来寄存;

* LinkedHashSet:以元素刺进的次第来保护调集的链接表,答应以刺进的次第在调集中迭代;

* TreeSet:供给一个运用树结构存储Set接口的完成,目标以升序次第存储,拜访和遍历的时刻很快。

* @author Zhou-Jingxian

*

*/

public class SetDemo {

public static void main(String[] args) {

HashSet hs = new HashSet();

hs.add("B");

hs.add("A");

hs.add("D");

hs.add("E");

hs.add("C");

hs.add("F");

System.out.println("HashSet 次第:\n"+hs);

LinkedHashSet lhs = new Linke大竹爱子dHashSet();

lhs.add("B");

lhs.add("A");

lhs.add("D");

lhs.add("E");

lhs.add("C");

lhs.a西塘古镇,Java调集结构概述,田子坊dd("F");

System.out.println("LinkedHashSet 次第:\n"+lhs);

TreeSet ts = new TreeSet();

ts.add("B");

ts.add("A");

ts.add("D");

ts.add("E");

ts.add此面向上成果怎么做("C");

ts.add("F");

System.out.println("TreeSet 次第:\n"+ts);

}

}

输出成果:

HashSet 次第:[D, E, F, A, B, C]

LinkedHashSet 次第:[B, A, D, E, C, F]

TreeSet 次第:[A, B, C, D, E, F]

5、Iterator和ListIterator差异

咱们在运用List,Set的时分,为了完成对其数据的遍历,咱们常常运用到了Iterator(迭代器)。运用迭代器,你不需求干与其遍历的进程,只需求每次取出一个你想要的数据进行处理就能够了。可是在运用的时分也是有不同的。

List和Set都有iterator()来获得其迭代器。对List来说,你也能够经过listIterator()获得其迭代器,两种迭代器在有些时分是不能通用的,Iterator和ListIterator首要差异在以下方面:

  • ListIterator有add()办法,能够向List中增加目标,而Iterator不能
  • ListIterator和Iterator都有hasNext()和next()办法,能够完成次第向后遍历,可是ListIterator有hasPrevious()和previous()办法,能够完成逆向(次第向前)遍历。Iterator就不能够。
  • ListIterator能够定位当时的索引方位,nextIndex()和previousIndex()能够完成。Iterator没有此功用。
  • 都可完成删去目标,可是ListIterator能够完成目标的修正,set()办法能够完成。Iierator仅能遍历,不能修正。

由于ListIterator的这些功用,能够完成对LinkedList等List数据结构的操作。其实,数组目标也能够用迭代器来完成。

6、Collection 和 Collections差异

(1)java.util.Collection 是一个调集接口(调集类的一个尖端接口)。它供给了对调集目标进行根本操作的通用接口办法。Collection接口在Java 类库中有许多详细的完成。Collection接口的含义是为各种详细的调集供给了最大化的一致操作办法,其直接承继接口有List与Set翻开你的心结。

Collection

├List

│├LinkedList

│├ArrayList

│└Vector

│ └Stack

└Set

(2)java.util.Collections 是一个包装类(东西类/协助类)。它包括有各种有关调集操作的静态多态办法。此类不能实例化,就像一个东西类,用于对调集中元素进行排序、查找以及线程安全等各种操作,服务于Java的Collection结构。

代码示例:

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

public class TestCollections {

public static void main(String args[]) {

//留意List是完成Collection接口的

List list = new ArrayList();

double array[] = { 112, 111, 23, 456, 231 };

for (int i = 0; i < array.length; i++) {

list.add(new Double(array[i]));

}

Collections.sort(list);

for (int i = 0; i < array.length; i++) {

System.out.println(list.get(i));

}

// 成果:23.0 111.0 112.0 231.0 456.0

}

}

评论(0)