3.常用集合——Set集合、哈希表
i.AbstractSet<E>(1.2)类和AbstractMap<K,V>(1.2)相关:
Set和Map部分需要进行比较方式讲解可能更能够理解里面每一种集合的用法
1)HashSet<E>(1.2)、HashMap<K,V>(1.2)和HashTable<K,V>(1.0)
HashSet<E>(1.2)类:
public classHashSet<E>extendsAbstractSet<E>implementsSet<E>,Cloneable,Serializable
该类实现了接口Set,由哈希表支持[实际是一个HashMap实例],它不保证集合的迭代顺序,特别是不保证顺序恒久不变,但是允许null元素。对该集合迭代使用的时间和HashSet实例的大小(元素的数量)和底层的HashMap实例(桶的数量)的“容量”的和成比例,如果迭代性在程序设计的时候很重要,不要将初始化容量设置得太高。该实现不是同步的,而且其遍历方法等同于数组,都是快速失败的,若需要对该集合进行同步方法就需要调用下边的方法:
Set s = Collections.synchronizedSet(newHashSet(...));
HashMap<K,V>(1.2)类:
public classHashMap<K,V>extendsAbstractMap<K,V>implementsMap<K,V>,Cloneable,Serializable
该类是基于哈希表的Map接口实现,此实现提供了所有可选的映射操作,并且允许使用null值和null键。(除了非同步和允许使用null之外,HashMap类和Hashtable类大致相同。),同样的该类不保证映射的顺序,特别是它不保证该顺序恒久不变。HashMap的实例有两个影响性能的参数:初始容量和加载因子
容量是哈希表中的桶的数量,初始容量就是哈希表在创建的时候的容量。
加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。
当哈希表中的条目数超出了加载因子和当前容量的乘积的时候,需要针对哈希表结构进行重建操作,而哈希表内部具有大约两倍的桶数目。
Hashtable<K,V>(1.0)类:
public classHashtable<K,V>extendsDictionary<K,V>implementsMap<K,V>,Cloneable,Serializable
该类是HashMap的前身,主要特点和HashMap<K,V>差不多,但是有一点点区别就是:键和值都不允许使用null,而且该类的实现是线程同步的。
先看几个简单的例子,再来考虑它们相互之间的一些区别和联系
——[1]HashSet<E>的基本例子——
packageorg.susan.java.collection;
importjava.util.Arrays;
importjava.util.HashSet;
importjava.util.Iterator;
importjava.util.Set;
/**
*一个使用HashSet的简单例子
**/
public classHashSetDemo {
public static voidmain(Stringargs[]){
HashSet<String> set =newHashSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("B");
set.add("D");
printSet(set);
System.out.println();
String[] strArray = {"E","F","G"};
set.addAll(Arrays.asList(strArray));
printSet(set);
}
private static voidprintSet(Set<String> set){
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
System.out.print("["+ iterator.next() +"],");
}
}
}
根据上边这段代码可以得到下边的输出:【*:因为集合本身是无序的,而且迭代不保证顺序,有可能输出的顺序不一样,但是集合元素的内容应该是相同的。】
[D],[A],[B],[C],
[D],[E],[F],[G],[A],[B],[C],
——[2]从HashSet<E>里面删除某个元素——
packageorg.susan.java.collection;
importjava.util.HashSet;
importjava.util.Iterator;
importjava.util.Set;
/**
*HashSet的删除方法remove(Object obj)
**/
public classHashSetDemo {
public static voidmain(Stringargs[]){
HashSet<Integer> set =newHashSet<Integer>();
set.add(newInteger(12));
set.add(newInteger(33));
set.add(55);
set.remove("B");
set.remove(12);
printSet(set);
}
private static voidprintSet(Set<Integer> set){
Iterator<Integer> iterator = set.iterator();
while(iterator.hasNext()){
System.out.print("["+ iterator.next() +"],");
}
}
}
先看上边这段代码的结果:
[33],[55],
【*:与ArrayList的结果有区别的是,该remove方法只有一个参数Object,而且没有重载形式,因为HashSet本身是无序的,所以和ArrayList不一样的是,不支持索引,所以在删除的时候,进行了一次自动拆解箱的操作。注意代码set.remove(12),这个代码传入的是12的原始类型,但是在这个过程里面转换成为了Integer的类型。如果这一段是ArrayList类型而不是HashSet类型,就会抛出异常,因为ArrayList有一个带int类型的重载方法,是删除某个索引位置的元素,而且HashSet的remove方法如果删除失败的话不会抛出异常,因为是返回的一个特殊值false,这一点可以直接在代码中修改set.remove("B")为System.out.println(set.remove("B"))来验证】
——[3]HashMap<K,V>的不同遍历——
packageorg.susan.java.collection;
importjava.util.Collection;
importjava.util.HashMap;
importjava.util.Iterator;
importjava.util.Set;
importjava.util.Map.Entry;
/**
*使用HashMap的基本例子
**/
public classHashMapDemo {
public static voidmain(Stringargs[]){
HashMap<Integer,String> map =newHashMap<Integer,String>();
map.put(1,"One");
map.put(2,"Two");
map.put(3,"Three");
map.put(4,"Four");
//键遍历
System.out.println("------Key Iterator------");
Set<Integer> keys = map.keySet();
Iterator<Integer> iterator = keys.iterator();
while(iterator.hasNext()){
Integer key = iterator.next();
System.out.print("[Key:"+ key +"--");
System.out.println("Value:"+ map.get(key) +"]");
}
// 值遍历
System.out.println("------Value Iterator------");
Collection<String> values = map.values();
Iterator<String> vIterator = values.iterator();
while(vIterator.hasNext()){
Stringvalue = vIterator.next();
System.out.println("[Value:"+ value +"]");
}
//映射关系遍历
System.out.println("------Entry Iterator------");
Set<Entry<Integer,String>> set = map.entrySet();
Iterator<Entry<Integer,String>> sIterator = set.iterator();
while(sIterator.hasNext()){
Entry<Integer,String> entry = sIterator.next();
System.out.print("[Key:"+ entry.getKey() +"--");
System.out.println("Value:"+ entry.getValue() +"]");
}
}
}
这里提供了三种不同的方式遍历,有几点需要说明:
- 通过键遍历的时候,键使用的返回是Set<E>,因为键是一个不重复的,所以为了保证键的不重复性,设计的时候使用的Set<E>
- 通过值遍历的时候,值使用的时候返回是Collection<E>,因为该集合是可以重复的,而且不需要保证值的不重复性
- 通过关系遍历的时候,使用的格式需要注意Entry是Map的内部类Map.Entry,而且每一个项的类型需要注意
- 只能通过Map的键去获取值,不能通过Map的值去获取键
下边是这段程序的输出:
------Key Iterator------
[Key:1--Value:One]
[Key:2--Value:Two]
[Key:3--Value:Three]
[Key:4--Value:Four]
------Value Iterator------
[Value:One]
[Value:Two]
[Value:Three]
[Value:Four]
------Entry Iterator------
[Key:1--Value:One]
[Key:2--Value:Two]
[Key:3--Value:Three]
[Key:4--Value:Four]
——[4]Hashtable<K,V>的简单用法——
packageorg.susan.java.collection;
importjava.util.Enumeration;
importjava.util.Hashtable;
public classHashtableDemo {
public static voidmain(Stringargs[]){
Hashtable<Integer,String> tables =newHashtable<Integer,String>();
tables.put(1,"One");
tables.put(2,"Two");
tables.put(3,"Three");
Enumeration<Integer> iterator =null;
for(iterator = tables.keys();iterator.hasMoreElements();){
Integer key = iterator.nextElement();
System.out.print("[Key:"+ key +"--");
System.out.println("Value:"+ tables.get(key) +"]");
}
}
}
上边代码的程序输出:
[Key:3--Value:Three]
[Key:2--Value:Two]
[Key:1--Value:One]
【*:从上边的代码段可以看出,HashMap和Hashtable没有太多的区别,所以这段代码仅仅提供Hashtable的键遍历方式就可以了,至于遍历是使用for还是使用while,这个可以根据本身的情况自行选择。而且需要注意一点是HashMap在遍历的时候返回的迭代器是Iterator,而Hashtable返回的迭代器是Enumeration。】
上边的代码段都是1.5过后带泛型的代码段,下边提供一段老版本(1.4或者1.4以下的版本)的写法:
packageorg.susan.java.collection;
importjava.util.HashMap;
importjava.util.Iterator;
importjava.util.Map.Entry;
public classOleMap {
public static voidmain(Stringargs[]){
HashMap map =newHashMap();
map.put(1,"One");
map.put(2,"Two");
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext())
{
Entry entry = (Entry)iterator.next();
System.out.print("[Key:"+ entry.getKey() +"--");
System.out.println("Value:"+ entry.getValue()+"]");
}
}
}
这段代码的输出这里不列出来了,老版本的写法没有泛型概念,就会出现一个类型的强制转换过程,在理解的时候可能简单很多,不过这种写法用1.5编译的时候会存在很多类型检查的警告。
上边已经基本接触了Hashtable和HashMap,总结一下这两个的特点和相互之间的区别,因为HashSet本身不是一个映射表的概念,就可以当作一个普通的Set集合的实现来使用,所以HashSet加入比较是没有太大的实际意义:
- 返回的迭代器不一样:Hashtable返回的迭代器是Enumeration,而HashMap返回的迭代器是Iterator
- HashMap不是同步的,而Hashtable是线程同步的,意思就是说前者是线程不安全的,系统开销比较小;后者是线程安全的,开销相对大点点
- HashTable不允许null键和null值,而HashMap是允许null键和null值的
- HashTable有一个contains(Object value)方法和containsValue(Object value)的功能是一模一样的
最后再介绍一下上边代码没有涉及到的常用方法:
HashMap<K,V>类:
booleancontainsKey(Object key):如果该映射里面包含了指定的一个键的映射关系返回为true,反之返回为false
booleancontainsValue(Object value):如果该映射里面包含了指定的一个或者多个值的映射关系,返回为true,反之返回为false
voidputAll(Map<?extendsK,?extendsV> m):不单独复制某个映射关系,而是直接把一个映射关系复制到某个映射里面,类似集合中的addAll方法
Hashtable<K,V>类:
booleancontains(Object value):如果该映射里面包含了指定的一个或者多个值的映射关系,返回为true,反之返回为false
booleancontainsKey(Object key):如果该映射里面包含了指定的一个键的映射关系返回为true,反之返回为false
booleancontainsValue(Object value):如果该映射里面包含了指定的一个或者多个值的映射关系,返回为true,反之返回为false
Enumeration<V>elements():返回哈希表中的值的枚举
Collection<V>values():返回哈希表中的值的集合
Enumeration<K>keys():返回哈希表中的键的枚举
Set<K>keySet():返回哈希表中的键的集合
protected voidrehash():重组该hash表。
这里注意区分返回为键枚举以及键集合的方法和返回为值枚举和值集合的方法【elements() && values();keys() && keySet()】
2)TreeSet<E>(1.2)类TreeMap(K,V>(1.2)类:
上边介绍的HashSet和HashMap都是无序的,接下来介绍两个有序的映射:
TreeSet<E>(1.2)类:
public classTreeSet<E>extendsAbstractSet<E>implementsNavigableSet<E>,Cloneable,Serializable
基于TreeMap的NavigableSet实现,使用元素的自然顺序对元素进行排序,或者根据创建的Comparator进行排序。
——[$]TreeSet简单例子——
packageorg.susan.java.collection;
importjava.util.Iterator;
importjava.util.TreeSet;
/**
*TreeSet集合的一个例子
**/
public classTreeSetDemo {
public static voidmain(Stringargs[]){
TreeSet<Integer> tree = new TreeSet<Integer>();
tree.add(22);
tree.add(11);
tree.add(33);
tree.add(44);
System.out.println(tree);
Iterator<Integer> iterator = tree.iterator();
while(iterator.hasNext()){
System.out.print(iterator.next() +",");
}
System.out.println();
iterator = tree.descendingIterator();
while(iterator.hasNext()){
System.out.print(iterator.next() +",");
}
}
}
上边这段代码演示了TreeSet的基本用法,其实TreeSet有一个很大的特点,不论用什么样子的方式将元素添加到这个集合里面,这个集合里面的元素总是通过某个比较器进行了排序操作的,可以看下边的输出:
[11, 22, 33, 44]
11,22,33,44,
44,33,22,11,
从上边的结果可以知道,TreeSet本身就是已经排好序的集合,所以正序遍历结果和本身内部的结果一样的顺序,虽然添加的时候是22,11,33,44。至于TreeSet的方法,大部分和Set差不多,这里不做详细介绍,有兴趣的可以去查阅以下API。
——[$]TreeMap简单例子——
介于红黑树(Red-Block tree)的NavigableMap实现,该映射根据键的自然排序进行排序,或者根据键的Comparator进行排序
packageorg.susan.java.collection;
importjava.util.Iterator;
margin-top: 0px; margin-bottom:
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
Java集合、泛型和枚举;Java集合、泛型和枚举;Java集合、泛型和枚举;Java集合、泛型和枚举;
java集合 框架 泛型,枚举,有PPT详解,并有实例
FileList.java 自己实现的一个文件名称枚举类 MyDataIO.java 数据输入输出示例 MyFileOutput.java 将键盘读入的文字保存到文件 MyPipedIO.java 管道流示例 MySequenceIn.java 顺序输入流示例 ObjectFileTest....
..........Java中的IO .....I/O_BIO ..........I/O流对象与使用 ..........文件相关类的使用 .....集合 ..........概述 ..........集合API .....线程 ..........概念 ..........操作线程 ..........线程安全-使用...
2.2. Java中基本概念 3. 二 定义,关键字和类型 3.1. 注释的三种形式 3.2. Java代码中的“;”、“{}”、“ ” 3.3. 标识符 3.4. 数据类型 3.5. 命名规则 4. 三 表达式和控制流 4.1. 变量和作用域 4.2. 操作...
5. Collection集合、数据结构、List集合、泛型、Set集合、可变参数 6. 集合工具类Collections、Map集合、集合嵌套、不可变集合 7. Stream流、异常处理 8. Logback日志框架、阶段项目 9. File、方法递归、字符集、IO...
泛型.docx 封装和继承以及多态部分.docx 接口和抽象类以及实现类.docx 枚举enum.docx 设计模式.docx 数组.docx 网络编程.docx 线程和内部类.docx 循环和类对象.docx 异常.docx 正则表达式.docx 总结.docx
9 Java GUI 日历:使用swing和awt实现一个图形化的日历可以查询星期、日期和年份信息(CalenderTrain.java);标准计算器(Callulator.java);更改组建外观,对日历设置几个显示外观(lookandfeel.java);自定义...
Java基础 Java集合.pptx Java基础反射pptx Java基础 多线程.pptx Java基础 异常处理pptx Java基础 枚举&注解pptx Java基础泛型docx Java基础_网络编程pptx Java基础面向对象pptx Java基础_高级类特性.pptx Java基础...
Java SE完整版精品优质课件 自学入门必看的优秀Java基础知识培训教案 ...第7章 Java集合 第8章 泛型 第9章 注解&枚举 第10章 IO 第11章 多线程 第12章 Java常用类 第13章 Java反射 第14章 网络编程
Java基础知识 第07章_Java集合(共51页).pptx Java基础知识 第08章_泛型(共22页).pptx Java基础知识 第09章_枚举&注解(共22页).pptx Java基础知识 第10章_IO(共56页).pptx Java基础知识 第11章_多线程(共54页).pptx ...
2.2. Java中基本概念 2-5 3. 二•定义,关键字和类型 3-5 3.1. 注释的三种形式 3-5 3.2. Java代码中的“;”、“{}”、“ ” 3-5 3.3. 标识符 3-5 3.4. 数据类型 3-6 3.5. 命名规则 3-6 4. 三•表达式和控制流 4-6 ...
泛型与继承、类型擦除、泛型中K T V E ? 、泛型各种用法 限定通配符和非限定通配符、上下界限定符extends 和 super List和原始类型List之间的区别? List<?>和List之间的区别是什么? 单元测试 junit、mock、...
ava基础 基础知识 面向对象基础 Java基本数据类型 string和包装类 final关键字特性 Java类和包 抽象类和接口 代码块和代码执行顺序 Java自动拆箱装箱里隐藏的秘密 ...Java集合详解8:Java集合类细节精讲 JavaWeb
2.2. Java中基本概念 2-5 3. 二•定义,关键字和类型 3-5 3.1. 注释的三种形式 3-5 3.2. Java代码中的“;”、“{}”、“ ” 3-5 3.3. 标识符 3-5 3.4. 数据类型 3-6 3.5. 命名规则 3-6 4. 三•表达式和控制流 4-6 ...
Java SE完整版精品优质课件 自学入门必看的优秀Java基础知识培训教案 ...第7章 Java集合 第8章 泛型 第9章 注解&枚举 第10章 IO 第11章 多线程 第12章 Java常用类 第13章 Java反射 第14章 网络编程
Java SE完整版精品优质课件 自学入门必看的优秀Java基础知识培训教案 ...第7章 Java集合 第8章 泛型 第9章 注解&枚举 第10章 IO 第11章 多线程 第12章 Java常用类 第13章 Java反射 第14章 网络编程
这个更新版的Java in a Nutshell不仅可以帮助有经验的Java程序员充分利用Java版本9到11,它...使用Java集合并处理常见的数据格式 深入研究Java最新的I / O API,包括异步通道 使用Nashorn在Java虚拟机上执行jаvascript
Java.IO Java.lang Java.math Java.net等思维导图,帮助你快速入门java核心技术卷I 注意:不包括多线程并发,网络编程复杂知识点!!!!!