- 1️⃣ 双列对象保存:Map
-
-
- 1.1 HashMap 类与 Hashtable 类
- 1.2 使用 lterator 获取 Map 集合元素
- 1.3 自定义 Map 集合的 key 类型
- 1.4 LinkedHashMap 类
- 1.5 TreeMap 类
- 1.6 Properties 类
- 1.7 HashMap和 Hashtable的区别
-
- 2️⃣ Collections 工具类
- * 总结

1️⃣ 双列对象保存:Map
Collection 每次只能保存一个对象,所以属于单值保存父接口。而在类集中又提供了保存双列对象的集合:Map 集合,利用 Map 集合可以保存一对关联数据 (按照 “key = value”的形式),如下所示,这样就可以实现根据 key 取得 value 的操作。

图1Collection 与 Map 保存的区别
下面是Map体系的主要类继承关系:

图2Map 体系类继承关系
可以看到,Map接口是所有Map体系类的根接口,其中定义了一些基本的操作方法,如put()、get()、remove()等;AbstractMap是一个抽象类,它实现了Map接口的骨架实现,提供了一些通用的功能。其他具体的Map类通常继承自它。
而最常用的子类有: 使用哈希表实现的HashMap,它允许使用null作为键或值,并且不保证元素的顺序;基于链表实现的LinkedHashMap,它保持插入顺序或访问顺序(可选); 还有基于红黑树实现的TreeMap,它支持按照键的自然排序进行排序,或者通过Comparator比较器自定义指定顺序。
而ConcurrentMap 接口则扩展了Map接口,定义了一些支持并发访问的方法;ConcurrentHashMap 是线程安全的哈希表实现的Map,支持高并发操作,并允许在遍历时进行修改操作。这两个类都是JUC包中的对多线程并发安全做支撑的类,对于这两个类将在我后续的专栏《高并发编程》中详细介绍,敬请期待。
Hashtable则是一个旧版的哈希表实现的Map,线程安全,但性能较低,不推荐使用。它的功能与HashMap类似,但不允许使用null作为键或值。Properties 是一个特殊的Hashtable子类,主要用于处理属性文件。它允许通过键-值对表示配置信息,并提供了一些方法方便地读取和写入这些配置信息。
在Map 接口中的常用方法如下所示。
| 方法名称 | 描述 |
|---|---|
int size() |
返回Map中键值对的数量 |
boolean isEmpty() |
检查Map是否为空 |
boolean containsKey(Object key) |
检查Map中是否包含指定的键 |
boolean containsValue(Object value) |
检查Map中是否包含指定的值 |
V get(Object key) |
返回指定键对应的值 |
V put(K key, V value) |
将键值对添加到Map中 |
V remove(Object key) |
根据键删除Map中对应的键值对 |
void putAll(Map<? extends K, ? extends V> m) |
将另一个Map中的所有键值对添加到当前Map中 |
void clear() |
清空Map中的所有键值对 |
Set<K> keySet() |
返回Map中所有键组成的集合 |
Collection<V> values() |
返回Map中所有值组成的集合 |
Set<Map.Entry<K, V>> entrySet() |
返回Map中所有键值对组成的集合 |
default V getOrDefault(Object key, V defaultValue) |
返回指定键对应的值,如果键不存在则返回默认值 |
default V putIfAbsent(K key, V value) |
当指定的键不存在时,将键值对添加到Map中 |
这些方法提供了在Map中添加、获取、删除键值对,以及检查Map的状态和遍历Map的能力。需要根据具体情况选择适当的方法来完成所需的操作。
1.1 HashMap 类与 Hashtable 类
在Map 接口中存在两个常用的子类: HashMap、Hashtable,下面先介绍这两个子类的使用。
// 范例 1: 观察HashMap 子类的使用
package com.xiaoshan.demo;
import java.util.HashMap;
import java.util.Map;
public class TestDemo {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<String, Integer>(); //定义Map 集合
map.put("壹",1); //保存数据
map.put("贰",2);
map.put("叁",3);
map.put("叁",33); //key数据重复
map.put("空",null); // value为null
map.put(null,0); // key为null
System.out.println(map); //输出map集合
}
}
程序执行结果:
(贰=2, null=0, 叁=33, 壹=1, 空=null)
程序实现了 Map 最为基础的数据保存操作,在实例化 Map 接口对象时首先需要明确地指定泛型类型,此处指定 key 的类型为 String, value 的类型为 Integer, 然后利用 put()方法进行数据的保存。特别需要注意的是,在进行数据保存时,如果出现了key 重复的情况,就会使用新的数据覆盖或替换已有数据。
通过上边范例的操作可以发现 Map 如下特点:
- 使用HashMap 定义的Map 集合是无序存放的;
- 如果发现了重复的 key 会进行值的覆盖,使用新的内容替换旧的内容;
- 使用HashMap 子类保存数据时 key 或 value 允许保存 null。
但需要注意的是,上边范例的代码只是演示了 Map 的基本使用,然而 Map 保存数据的目的并不是进行输出操作,而常常是为了进行查找,即利用 get() 方法通过 key 获取到对应的 value 数据。
// 范例 2: 查询操作
package com.xiaoshan.demo;
import java.util.HashMap;
import java.util.Map;
public class TestDemo {
public static void main(String[] args){
Map<String, Integer> map =new HashMap<String,Integer>(); // 定义Map 集合
map.put("壹",1); //保存数据
map.put("贰",2);
map.put("叁",3);
map.put("叁",33); //key数据重复
map.put("空",null); // value为null
map.put(null,0); // key为null
System.out.println(map.get("壹")); //key存在返回value
System.out.println(map.get("陸")); //如果key不存在,返回null
System.out.println(map.get(null)); // key存在
}
}
程序执行结果:
1
null
0
此程序利用 Map 接口中的 get()方法根据 key 取得了其对应的 value 内容,通过执行结果可以发现,如果指定的key 存在则会返回与之对应的 value, 而如果 key 不存在则返回 null。
通过范例2的代码可以发现,Map 接口在使用中依然只是保存数据与获取数据,那么为什么不直接使用Collection呢,为什么还需要Map接口呢?
首先Collection与 Map 接口都可以保存动态长短的数据,然而两者本质的区别在于其使用的环境。Collection接口保存数据的主要目的是输出(利用 Iterator接口)而 Map 保存数据的目的是实现 key查找value的字典功能,虽然Map也可以进行输出操作,但是这样的操作在开发中出现较少。
在Map 接口下还有一个 Hashtable 的子类,此类是在JDK 1.0时提供的,属于最早的Map 集合的实现操作。在JDK 1.2时 Hashtable 的子类多实现了一个Map 接口,从而得以保存下来继续使用。
Hashtable 与HashMap 都属于Map接口的子类,所以从本质上讲,它们最终都会利用子类向上转型为Map接口对象实例化。但是在使用Hashtable子类实例化的Map 集合中,保存的key或value都不允许出现null,否则会出现"NullPointerException" 异常 。
// 范例 3: 使用 Hashtable
package com.xiaoshan.demo;
import java.util.Hashtable;
import java.util.Map;
public class TestDemo {
public static void main(String[] args){
Map<String, Integer> map =new Hashtable<String, Integer>(); // 定义Map 集合
map.put("壹",1); //保存数据
map.put("贰",2);
map.put("叁",3);
map.put("叁",33); //key 数据重复
System.out.println(map.get("壹")); // key存在返回value
System.out.println(map.get("陸")); //key 不存在,返回null
}
}
程序执行结果:
1
null
此程序利用 Hashtable 子类实例化了 Map 接口,由于接口操作标准统一,所以 put()与 get()方法都可以正常使用,在使用 get()方法进行数据查找时,如果数据不存在则返回 null。
在实际开发中,由于 HashMap 保存数据不受 null 的限制,所以建议优先考虑使用HashMap 子类。
1.2 使用 lterator 获取 Map 集合元素
首先大家必须明确一个开发原则:集合的输出要利用 Iterator 接口完成。但是 Map 接口与 Collection 接口在定义上有所不同, Map 接口并没有提供直接取得 Iterator 接口对象的方法。所以如果要使用 Iterator 输出 Map 接口数据,就必须要清楚 Collection 接口与 Map 接口在数据保存形式上的区别,如下图所示。

图3Collection 与 Map 集合数据存储区别
可以发现,当用 Collection 集合保存数据时所有的对象都是直接保存的。而用 Map 集合保存数据时,所保存的 key 与 value 会自动包装为 Map.Entry 接口对象,也就是说如果利用 Iterator 进行迭代,那么每当使用 next()方法读取数据时返回的都是一个 Map.Entry 接口对象,此接口定义如下。
public static interface Map.Entry<K,V>{
}
通过定义可以发现,Map.Entry 接口属于 Map 接口中定义的一个 static 内部接口(相当于外部接口)。Map.Entry 接口定义的常用方法如下所示。
| 方法 | 类型 | 描述 |
|---|---|---|
public K getKey() |
普通 | 取得数据中的key |
public V getValue() |
普通 | 取得数据中的value |
public V setValue(V value) |
普通 | 修改数据中的value |
清楚了Map.Entry 接口作用后就可以来研究如何利用 Iterator 接口输出 Map 集合了,在 Map 接口中定义了一个 entrySet()方法:public Set<Map.Entry<K,V>> entrySet(),而实现 Map 接口输出的关键就在于此方法的使用上。
Iterator 输出 Map 集合的操作步骤如下:
(1)利用 entrySet()方法将 Map 接口数据中的数据转换为 Set 接口实例进行保存,此时 Set 接口中所使用的泛型类型为 Map.Entry, 而 Map.Entry 中的 K 与 V 的泛型类型则与 Map 集合定义的 K 与 V 类型相同;
(2)利用Set接口中的 iterator() 方法将Set 集合转化为 Iterator 接口实例;
(3)利用 Iterator 接口进行迭代输出,每一次迭代取得的都是 Map.Entry 接口实例,利用此接口实例可以进行 key 与 value的分离获取。
// 范例 4: 利用 Iterator 实现Map接口的输出
package com.xiaoshan.demo;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TestDemo {
public static void main(String[] args){
Map<String, Integer> map = new Hashtable<String,Integer>();// 定义Map 集合
map.put("壹",1); //保存数据
map.put("贰",2);
map.put("叁",3);
map.put("叁",33); //key数据重复
Set<Map.Entry<String,Integer>> set = map.entrySet(); //将Map集合变为Set集合,目的是使用iterator()方法,注意泛型的统一
Iterator<Map.Entry<String,Integer>> iter = set.iterator(); //取得Iterator实例
while (iter.hasNext()){
//迭代输出
Map.Entry<String,Integer> entry = iter.next(); //取出Map.Entry
System.out.println(entry.getKey()+" = "+ entry.getValue()); // 输出数据
}
}
}
程序执行结果:
贰 = 2
壹 = 1
叁 = 33
程序按照给出的步骤实现了Iterator 接口输出 Map 集合的操作,其中最为关键的就是 Iterator 每次迭代返回的类型是Map.Entry (注意泛型类型的设置), 而后利用 getKey() 与 getValue()方法才可以取得所保存的 key 与 value数据。
1.3 自定义 Map 集合的 key 类型
在使用Map 接口时可以发现,几乎可以使用任意的类型来作为 key 或 value 的存在,也就表示可以使用自定义的类型作为 key。但要注意的是,作为key 的自定义的类必须要覆写 Object 类中的 hashCode() 与 equals() 两个方法,因为只有靠这两个方法才能确定元素是否重复,也即确认在Map 中能否找到元素,能找到则说明已有相同元素,再根据确认结果进行存储或覆盖等操作。
// 范例 5: 使用自己定义的类作为 Map 集合的key
package com.xiaoshan.demo;
import java.util.HashMap;
import java.util.Map;
class Book {
//此类为要保存的 key 类型
private String title; //只定义一个属性
public Book(String title){
//构造方法接收数据
this.title = title;
}
@Override
public String toString(){
return "书名:"+ this.title;
}
@Override
public int hashCode(){
//取得对象编码
final int prime =31;
int result =1;
result = prime* result + (title == null) ? 0 : title.hashCode();
return result;
}
@Override
public boolean equals(Object obj){
//进行对象比较
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book other = (Book) obj;
if (title == null){
if (other.title != null){
return false;
}
}else if (!title.equals(other.title)){
return false;
}
return true;
}
}
public class TestDemo {
public static void main(String[] args){
Map<Book,String> map = new HashMap<Book,String>(); //实例化Map 接口集合
map.put(new Book("Java开发"),new String("Java")); //向Map 接口保存数据
System.out.println(map.get(new Book("Java开发"))); //根据key 取得value
}
}
程序执行结果:
Java
此程序使用一个自定义的Book 类作为 Map 集合中的 key 类型,由于已经正确地覆写了 hashCode() 与 equals()方法,因此可以在 Map 集合中根据 key 找到对应的 value数据。
虽然Map集合中可以将各种数据类型作为 key进行设置,但是从实际的开发来讲,不建议使用自定义类作为key,建议使用Java中提供的系统类作为key,如String、Integer等,其中String作为key的情况是最为常见的。
1.4 LinkedHashMap 类
LinkedHashMap是Java中提供的一种基于链表和哈希表实现的有序Map。它继承自HashMap,并添加了一个双向链表用于维护插入顺序或访问顺序。
与普通的HashMap不同,LinkedHashMap会保持元素的插入顺序或访问顺序。具体来说,LinkedHashMap维护了一个双向链表,每个节点都有指向前一个节点和后一个节点的引用。通过这个链表,LinkedHashMap可以按照元素的插入顺序或最近访问的顺序进行迭代。
下面是一个使用LinkedHashMap的代码示例,展示了如何保持元素的插入顺序以及访问顺序:
// 范例 6: LinkedHashMap 保持元素的插入顺序以及访问顺序
package com.xiaoshan.demo;
import java.util.LinkedHashMap;
import java.util.Map;
public class TestDemo {
public static void main(String[] args) {
// 创建一个具有默认插入顺序的LinkedHashMap
Map<String, Integer> map = new LinkedHashMap<>();
// 添加键值对到LinkedHashMap
map.put("Apple", 10);
map.put("Banana", 5);
map.put("Orange", 8);
// 遍历输出元素,按照插入顺序进行迭代
System.out.println("按照插入顺序遍历LinkedHashMap:");
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 创建一个具有自定义访问顺序(访问后放到最后)的LinkedHashMap
Map<String, Integer> accessOrderedMap = new LinkedHashMap<>(16, 0.75f, true);
accessOrderedMap.put("Apple", 10);
accessOrderedMap.put("Banana", 5);
accessOrderedMap.put("Orange", 8);
// 遍历输出元素,按照访问顺序进行迭代
System.out.println("按照访问顺序遍历LinkedHashMap:");
// 先访问一次"Banana"
accessOrderedMap.get("Banana");
// 再遍历输出时会将"Banana"放到最后
for (Map.Entry<String, Integer> entry : accessOrderedMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
程序运行结果:
按照插入顺序遍历LinkedHashMap:
Apple: 10
Banana: 5
Orange: 8
按照访问顺序遍历LinkedHashMap:
Apple: 10
Orange: 8
Banana: 5
可以从结果发现,在默认情况下,LinkedHashMap会保持元素的插入顺序。而如果在构造LinkedHashMap时设置参数accessOrder为true,则会根据访问顺序进行迭代。当访问一个元素后,该元素会被移到链表的最后面。
1.5 TreeMap 类
TreeMap是Java集合框架中的一种有序映射实现类,它通过红黑树(一种自平衡二叉查找树)来维护键值对的有序性。
TreeMap将键值对按照键的自然排序或者通过指定的Comparator进行排序。默认情况下,使用键的自然顺序进行排序,要求键实现了Comparable接口。如果创建TreeMap时提供了Comparator对象,则会使用该Comparator来排序键。
由于红黑树保持了有序性,TreeMap可实现高效的检索、插入和删除操作。
下面是一个代码示例,演示了TreeMap在默认情况下使用键的自然顺序排序,以及当提供Comparator对象时使用该Comparator进行排序:
// 范例 7: TreeMap在默认情况下使用键的自然顺序排序,当提供Comparator对象时使用该Comparator进行排序
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
class Person implements Comparable<Person> {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public int compareTo(Person o) {
return this.name.compareTo(o.getName());
}
}
class ReversedNameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p2.getName().compareTo(p1.getName());
}
}
public class TreeMapSortExample {
public static void main(String[] args) {
// 默认情况下,TreeMap使用键的自然顺序进行排序
Map<Person, Integer> naturalOrderMap = new TreeMap<>();
naturalOrderMap.put(new Person("Alice"), 25);
naturalOrderMap.put(new Person("Charlie"), 20);
naturalOrderMap.put(new Person("Bob"), 30);
System.out.println("自然顺序排序:");
for (Person person : naturalOrderMap.keySet()) {
System.out.println(person.getName() + ": " + naturalOrderMap.get(person));
}
// 如果创建TreeMap时提供了Comparator对象,则使用该Comparator进行键的排序
Map<Person, Integer> customOrderMap = new TreeMap<>(new ReversedNameComparator());
customOrderMap.put(new Person("Alice"), 25);
customOrderMap.put(new Person("Charlie"), 20);
customOrderMap.put(new Person("Bob"), 30);
System.out.println("\n自定义顺序排序:");
for (Person person : customOrderMap.keySet()) {
System.out.println(person.getName() + ": " + customOrderMap.get(person));
}
}
}
在这个示例中,我们首先创建了一个Person类来作为TreeMap的键类型。Person实现了Comparable接口,通过实现compareTo()方法来定义其自然顺序。然后,我们创建了一个ReversedNameComparator类,它实现了Comparator接口,用于自定义键的排序。
接下来,我们分别创建了默认使用自然顺序排序的TreeMap和使用自定义排序的TreeMap。我们将Person对象作为键放入这两个TreeMap中,并将它们遍历输出。
程序运行结果:
自然顺序排序:
Alice: 25
Bob: 30
Charlie: 20
自定义顺序排序:
Charlie: 20
Bob: 30
Alice: 25
可以发现,在默认情况下使用键的自然顺序进行排序。由于Person实现了Comparable接口,可以按照姓名的字典顺序对键进行排序。而在创建TreeMap时提供了Comparator对象时,那么将使用该Comparator来排序键。我们创建了一个ReversedNameComparator对象来反向排序Person的键。
1.6 Properties 类
利用Map 集合可以将任意的数据类型设置为 Key 或 Value 的类型,虽然这样较为灵活,但是在某些开发中并不适用,所以在类集框架中提供了一个 Properties子类,利用此子类只能保存字符串类型的数据 (key=value)。
Properties 类本身属于 Hashtable 的子类,但是由于 Properties 类都使用 String 数据类型进行操 作,所以在使用Properties类时主要使用本类所定义的方法。 Properties类常用方法如表13-10所示。
| 方法 | 描述 |
|---|---|
Object setProperty(String key,String value) |
设置属性 |
String getProperty(String key) |
取得属性,如果key不存在则返回null |
String getProperty(String key, String defaultValue) |
取得属性,如果key不存在则返回默认值 |
void store(OutputStream out, String comments) throws IOException |
通过输出流保存属性内容,输出的同时可以设置注释信息 |
void load(InputStream inStream) throws IOException |
通过输入流读取属性内容 |
// 范例 8: 属性的基本操作
package com.xiaoshan.demo;
import java.util.Properties;
public class TestDemo{
public static void main(String[] args){
Properties pro = new Properties();
pro.setProperty("BJ","北京"); //保存属性信息
pro.setProperty("TJ","天津");
System.out.println(pro.getProperty("BJ")); //根据key取得属性信息
System.out.println(pro.getProperty("GZ"));
System.out.println(pro.getProperty("GZ","没有此记录")); //没有key返回默认值
}
}
程序执行结果:
北京
null
没有此记录
此程序是 Properties 类的基本操作,首先进行属性内容的设置,然后根据 key 取得指定的内容。在数据取得时如果有对应的 key 则可以直接输出 value, 如果没有对应的 key 并且设置了默认值,则会输出默认值。
利用Properties类还可以实现属性信息的输出流输出以及输入流读取操作,下面分别介绍这两个操作。
// 范例 9: 将属性信息保存在文件里
package com.xiaoshan.demo;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
public class TestDemo {
public static void main(String[] args) throws Exception {
Properties pro = new Properties();
pro.setProperty("BJ","北京"); //保存属性信息
pro.setProperty("TJ","天津");
//一般而言后缀可以随意设置,但是标准来讲,既然是属性文件,后缀就必须是*properties,这样做也是为了与国际化对应
//在进行属性信息保存时如果属性内容为中文则会自动进行转码操作
pro.store(new FileOutputStream(new File("D:"+ File.separator +"area.properties")),"Area Info");
}
}
此程序在属性设置完成后利用 store() 方法将属性内容设置到输出流中,由于使用的是文件输出流,所以最终属性的内容会保存在文件中,同时中文也会自动进行 UNICODE 编码转换。
当本机E 盘上存在了 area.properties 文件,那么就可以利用文件输入流 (FileInputStream) 来进行数据的读取。
// 范例 10: 通过文件流读取属性内容
package com.xiaoshan.demo;
import java.io.File;
import java.io.FilelnputStream;
import java.util.Properties;
public class TestDemo {
public static void main(String[] args) throws Exception {
Properties pro = new Properties(); //实例化类对象
pro.load(new FileInputStream(new File("E:"+ File.separator+"area.properties")));
System.out.println(pro.getProperty("BJ"); //根据key取得value
}
}
程序执行结果:
北京
此程序利用 load() 方法加载了文件输入流中的属性内容,随后就可以根据 key 取得属性内容了。
在进行属性信息读取时可以发现,前面文章讲解的 ResourceBundle与本节讲解的 Properties 类都支持属性文件(*.properties)的读取,那么在实际开发中使用哪一种呢?
Properties可以读取任意输入流,ResourceBundle 要结合国际化读取 *.prperties 文件。
ResourceBundle类在进行资源文件读取时只能读取后缀为“*.properties”的文件, 并且往往需要通过 Locale类来设置当前国家及语言环境。但是Properties类却可以不区分文件后缀,只要符合它保存数据的结构标准的输入流 (可能通过网络输入或用户输入) 数据都可以进行读取。理论上Properties在读取上更加灵活,但是ResourceBundle与 Locale类结合读取不同语言资源文件的功能 Properties 类并没有。
所以如果读取国际化资源文件使用 ResourceBundle类,如果读取一些配置信息则可以使用 Properties类。
1.7 HashMap和 Hashtable的区别
在Map接口中存在两个常用的子类:HashMap和Hashtable。尽管它们都是实现Map接口,但它们具有一些区别和特点。
HashMap:
- HashMap是Map接口的最常用实现类之一,它基于哈希表实现;
- 允许使用null作为键或值;
- 不保证元素的顺序,即不保证迭代顺序和插入顺序相同;
- 具有较好的性能,在大多数情况下提供高效的数据存储和检索操作;
- 非线程安全,若在多线程环境下使用需进行同步处理。
Hashtable:
- Hashtable是早期Java版本提供的哈希表实现的Map类,现在已被HashMap取代,但仍然在一些旧的代码中使用;
- 不允许使用null作为键或值,否则将抛出NullPointerException;
- 具有较好的性能,在大多数情况下提供高效的数据存储和检索操作;
- 通过使用synchronized关键字进行方法级别的同步,使其成为线程安全的实现;
- 不保证元素的顺序。
需要注意的是,由于Hashtable是线程安全的,可能会在某些应用中造成额外的开销。因此,在单线程环境下,推荐使用HashMap,而在多线程环境下,如需要保证线程安全,可选择使用Hashtable或者ConcurrentHashMap。
除了线程安全性和对空键值的处理方式之外,HashMap和Hashtable在用法和功能上基本相似。因此,大部分情况下,可以优先选择使用HashMap作为Map的实现类。
2️⃣ Collections 工具类
Java 提供类库时考虑到用户的使用方便性,专门提供了一个集合的工具类—— Collections, 这个工具类可以实现List、Set、Map 集合的操作。 Collections类的常用方法如下所示。
| 方法 | 描述 |
|---|---|
boolean addAll(Collection<? super T> c, T... elements) |
实现集合数据追加 |
int binarySearch(List<? extends Comparable<? super T>> list, T key) |
使用二分查找法查找集合数据 |
void copy(List<? super T> dest, List<? extends T> src) |
集合复制 |
void reverse(List<?> list) |
集合反转 |
void sort(List<T> list) |
集合排序 |
通过上面列出的方法可以发现, Collections 提供了一些更为方便的辅助功能操作。下面通过一个简单的范例来进行 Collections工具类的使用验证。
// 范例 11: 为集合追加数据
package com.xiaoshan.demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestDemo(
public static void main(String[] args) throws Exception{
List<String> all= new ArrayList<String>(); // 实例化集合对象
//利用Collections类的方法向集合保存多个数据
Collections.addAll("xiaoshan","XIAOSHAN","小山","hellojava","HELLOWORLD");
Collections.reverse(all); //集合反转
System.out.println(all); //直接输出集合对象
}
}
程序执行结果:
[HELLOWORLD, hellojava, 小山, XIAOSHAN, xiaoshan]
程序首先实例化了一个空的集合对象,然后利用 Collections 类的 addAll()方法一次性向集合中追加了多条数据,最后又利用 reverse()方法实现了集合数据的反转操作。
需要注意区别的是,Collection 是集合操作的接口,包含List子接口和Set子接口;Collections是集合操作的工具类,可以直接利用类中提供的方法,进行List、Set、Map等集合的数据操作。
* 总结
在本文中,我们探讨了双列对象保存的一些关键概念和技术。首先,我们比较了HashMap类和Hashtable类,它们都是常用的Map实现类,但有一些区别,例如线程安全性和对 null值的处理。接下来,我们介绍了使用迭代器(Iterator)来获取Map集合元素的方法,并演示了如何遍历Map中的键值对。然后,我们学习了自定义Map集合的键类型,并说明了为什么重写equals()和hashCode()方法对于正确的键值存储至关重要。
我们还介绍了其他一些常见的Map实现类,包括LinkedHashMap、TreeMap和Properties。最后,我们简要提及了Collections工具类,该工具类提供了一系列静态方法来操作集合,例如排序、查找和同步等。
通过本文的学习,我们对双列对象保存的不同实现和应用有了更深入的了解。根据不同的需求和特点,我们可以选择适合的Map实现类来满足我们的业务要求。同时,Collections工具类也是开发中非常有用的工具,可以提高集合处理的效率和便捷性。
希望本文对读者能够提供有价值的信息,并在开发中对双列对象保存和Collections工具类有所启发。
[
]nbsp_nbsp 4