集合类框架
1、集合类框架定义
在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类)。所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection Framework)。
Java.util中的集合类包含Java中某些常用的类。最常用的接口是List和Map。List的具体实现包括ArrayList和Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象元素列表。List适合用于按数值索引访问元素的情形。
下图是Java集合框架的结构图:
2、ArrayList
ArrayList是动态数组,支持自动改变大小,可以灵活的插入和删除元素。ArrayList定义了一些用于插入和删除元素的方法,具体如下:
方法 | 说明 |
add(E e) | 将指定的元素添加到此列表的尾部 |
clear() | 移除此列表中的所有元素 |
contains(Object o) | 如果此列表中包含指定元素,则返回true |
get(int index) | 返回此列表中指定位置上的元素 |
remove(int index) | 移除此列表中指定位置上的元素 |
toArray() | 按从第一个到最后一个元素的顺序返回包含次列表中所有元素的数组 |
如下代码实现便利ArrayList的实例:
package com.shiyanlou.course;
import java.util.ArrayList;
import java.util.List;
public class ArrayListTraversal {
public static void main(String[] args){
//创建列表list
List<Integer> list = new ArrayList<Integer>();
//使用add()方法,通过for循环向list中增加10个元素,每个元素即当前循环的次数值
for(int i = 0;i < 10;i++){
list.add(i);
}
System.out.println("Item in the list:");
//输出列表中全部元素
System.out.println(list);
System.out.println("Item in the list with odd index:");
//输出列表中序号为奇数的元素
for(int i = 1;i<list.size();i+=2){
//使用get()方法从list中取出元素
System.out.println(list.get(i));
}
}
}
3、HashMap
Java自带各种Map类,这些Map类可归为三种类型:
1)、通用Map(hashMap、Hashtable、Properties、LinkedHashMap、IdentityHashMap等);
2)、专用Map(java.util.jar.Attributes、javax.print.attribute.standard.PrinterStateReasons等);
3)、一个用于帮助实现用户自己的Map类的抽象类。
其中,通用Map用于在应用程序中管理映射,通常在java.util程序包中实现,可以直接使用。
Map定义了几个用于插入和删除元素的方法,通过这些方法可以更改Map中的内容:
方法 | 说明 |
clear() | 从 Map 中删除所有映射 |
remove(Object key) | 从 Map 中删除键和关联的值 |
put(Object key, Object value) | 将指定值与指定键相关联 |
get(Object key) | 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null |
clear() | 从 Map 中删除所有映射 |
putAll(Map t) | 将指定 Map 中的所有映射复制到此 map |
HashMap是基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用 null值和 null 键。
下面我们使用HashMap及其中的一些方法来做一个简单的电话簿,让用户通过输入待查询的姓名来获取其对应的电话号码。
package com.shiyanlou.course;
import java.util.HashMap;
import java.util.Scanner;
public class PhoneBookByMap {
public static void main(String[] args){
//创建一个HashMap对象,名称为phonebook,键值对的类型均为String
HashMap<String,String> phonebook = new HashMap<String ,String>();
//创建扫描器用于获取用户的输入
Scanner scan = new Scanner(System.in);
//创建一个名为keyword的字符串用于存放用户输入的关键词
String keyword = new String();
//利用自写的initPhoneBook方法为电话簿装入数据,完成其初始化的步骤
phonebook = initPhoneBook(phonebook);
// 提示用户输入待查询的姓名
System.out.println("Please input a name that you want to search:");
// 将用户的输入信息装入字符串keyword中
keyword = scan.nextLine();
while (keyword.isEmpty()){
System.out.println("Please input a name!");
keyword = scan.nextLine();
}
// 若用户有输入某个关键词,则按照该关键词在phonebook中查找其对应的号码,这里调用了自写的queryPhone()方法
System.out.println("The result is :");
System.out.println(queryPhone(phonebook, keyword));
scan.close();
}
private static HashMap<String,String> initPhoneBook(HashMap<String,String> phonebook){
// 该方法用于完成指定HashMap的初始化,为其装入一些号码数据,你也可以自定义这些数据
phonebook.put("Steve", "13012345678");
phonebook.put("Bob", "028-80001234");
phonebook.put("Peter", "182222233333");
// 使用put()方法将姓名与电话号码相关联,存放在名为phonebook的HashMap中
// put()方法中,第一个参数为关键词key,第二个参数为其对应的值value
return phonebook;
// 返回修改后的phonebook
}
private static String queryPhone(HashMap<String,String> phonebook,String keyword){
// 创建存放结果的字符串result
String result = new String();
// 使用get()方法查询keyword所对应的电话号码,并赋给result
// put()方法中,参数为关键词key,返回值为其对应的值value,未找到对应值时,返回值为null
result = phonebook.get(keyword);
if (result == null)
return "Can not find this user.";
// 如果未找到该用户的电话号码,则将查询结果修改为“未找到该用户”
return result;
// 返回查询结果
}
}
4
、Collection与Collections的区别
java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
5、List、Set和Map是否继承自Collection接口?
List、Set是,Map不是。
如图:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。
Java
JDK不能提供直接继承自Collection的类,
Java
JDK提供的类都是继承自Collection的"子接口",如:List和Set。
注意:Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当做一组key集合,一组value集合,或者一组key-value映射。
6、ArrayList与Vector的区别
首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList。List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。3个具体实现类的相关区别如下:
1)、ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
2)、Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
3)、LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
6、HashMap和HashTable的区别
HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。
1)、HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
2)、HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
3)、另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
4)、由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
5)、HashMap不能保证随着时间的推移Map中的元素次序是不变的。