java-集合

本文深入介绍了Java集合框架的各类容器,包括List、Set、Map的主要实现类及其应用场景,并提供了实例代码。

最近在LeetCode上刷题,发现用java集合代码量少很多,而且时间复发度也减少,因此就java集合做一个总结,有很多内容是参考网上代码。

java集合的框架类图


集合框架是一个统一的框架用来表示和操作的结合。框架主要有接口、抽象类、实现类构成。上图中实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。常用的几个类用黑色粗框标记:HashMap、ArrayList、LinkedList、hashSet

上图的简版表示:

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set

     |-HashSet

     |-LinkedHashSet

     |-TreeSet

Map
├Hashtable
├HashMap
└WeakHashMap

 |-TreeMap


List的三个常用实现类:

ArrayList类扩展AbstractList并执行List接口,ArrayList类支持可随需要而增长的动态数组。ArrayList类对于使用索引取出元素有较高的效率,它可以使用索引来快速定位对象。但元素做删除或插入速度较慢,因为使用了数组,需要移动后面的元素已调整索引顺序。

LinkedList类扩展AbstractSequentialList并执行List接口。它提供了一个链接列表数据结构,LinkedList容器类通过连接指针来关联前后两个元素。LinkedList是使用双向链表实现的容器,所以针对频繁的插入和删除元素使用LinkedList类效率较高,它适合实现栈和队列。

Vector类提供了实现可增长数组的功能,Vector类大多数操作与ArrayList类相同,区别在于Vector类是线程同步的。


Set 的三个常用实现类:

HashSet类是Set接口实现类之一,使用较广泛,它不保存元素的加入顺序。HashSet类根据元素的哈希码进行存放,取出时也可以根据哈希码快速找到。

LinkedHashSet类根据元素的哈希码进行存放,同时用链表记录元素加入的顺序。通过链表来存储对象,一般插入和删除效率较高,检索效率相对较低。

TreeSet类使用红黑树结构对加入的元素进行排序存放,通过TreeSet构造方法来获取TreeSet对象。

Map的常用实现类: 在存储键值对的时候, 通过指定的比较算法, 对键对象进行排序, 以二叉树形式进行存储.
  创建TreeMap时如果没有传入比较器, 则会按照键对象的自然顺序来排序. 自然顺序就是实现了Comparable接口之后compareTo方法中定义的顺序.如果我们不希望使用自然顺序排序, 还在TreeMap的构造函数中可以传入一个比较器. 比较器就是实现了Comparator接口的对象, 按照其中compare方法排序.

HashMap类: 在存储键值对的时候, 使用哈希算法对键对象去重复, 效率高, 没有顺序.
  当存储一个键值对的时候, 先调用键对象的hashCode()方法计算一个哈希值, 在集合中查找是否有哈希值相同键对象.
   如果没有哈希值相同的键对象, 直接将键值对存入.如果有哈希值相同键对象, 则和哈希值相同的键对象进行equals()比较.比较结果为false就存入键值对.比较结果为true则用新的值覆盖旧的值.

HashTable类:Hashtable和HashMap原理相同, 都是基于哈希算法的, Hashtable是线程安全的, 而且Hashtable不允许存储空的键和空的值.

TreeMap类:

针对以上做一个简短总结,主要从两方面来选择容器:

(1)存放要求

无序:Set,不能重复

有序:List,允许重复

“key-value”对:Map

(2)读写数据效率

Hash:两者都最高。

Array:读快改慢。

Linked:读慢改快。

Tree:加入元素可排序使用。


TreeMap类:

可以说如果按功能来分,集合类就由三部分组成:Iterator、Collection、Map;还有一点值得注意:Collection、Map都实现Iterator,因此,都可以调用hashNext()、next()、remove()迭代元素,对于LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious(),可以实现先序迭代。

下面讲讲如何使用

1.1Collection

Collection接口支持添加、去除、查询等基本操作

boolean add(Object element)

boolean remove(Object element)

int size()

boolean isEmpty()

boolean contrains(Object element)

Iterator iterator()

针对集合之间的交、并集也有专门的方法

boolean contrainsAll(Collection collection) 查询当前集合是否包含另一个集合的所有元素

boolean addAll(Collection collection)确保另一个集合中的所有元素都被添加到当前的集合中,即为并集

void clear() 在当前集合中去除所有元素

void removeAll(Collection collection)类似clear,但只去除元素的一个子集

void retainAll(Collection collection)从当前集合中去除不属于另一个集合的元素,即为交集

1.2List

除了拥有Collection的方法外,还拥有一些其他的方法

1.void add(int index, Object element);添加对象element到位置index上

2.boolean addAll(int index, Collection collection);在index位置后添加容器collection中所有的元素

3.Object get(int index);查找对象element在List中第一次出现的位置

4.int lastIndexOf(Object element);查找对象element在List中最后出现的位置

5.Object remove(int index);删除index位置上的element

6.Object set(int index,Object element);将index位置上

两种常规的List实现:ArratList和LinkedList

ArrayList:适合支持随机访问,不必在除尾部的任何位置插入或除去元素,类似于数组,只是可以自动增长

LinkedList:类似于链表,适合频繁从列表的中间位置添加和除去元素


1.2Map

1.value put(key,value);返回前一个和key关联的值

2.boolean containsKey(key);boolean containsValue(value)

3.value get(key)获取键值,没有键值,返回null

4.int size();获取键值的对数

5.Object remove(Object key)

6.public Set keySet();返回所有的键(key),并使用Set容器存放

7.public Set entrySet();返回一个实现Map.Entry接口的元素Set



注意:map没有迭代器,所以想取出map中的所以元素必须通过keyset方法获取map中所有的键所在的set集合,再通过set的迭代器获取到每一个键,再对每一个键通过map集合的get方法获取其对应的值即可


HashSet代码

/*time:2016-7-26 15:39:48
 * location:home
 * 
 * */
import java.util.*;
public class HashSetDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	HashSet<String> set = new HashSet<String>();
	set.add("a");
	set.add("b");
	set.add("c");
	set.add("c");
	set.add("d");
	
	//采用Iterator集合输出
	//这里怎么没有new创建对象,由工厂类创建吗
	Iterator<String> iter = set.iterator();
	while(iter.hasNext()){
		System.out.print(iter.next()+" ");
	}
	System.out.println();
	// 输出:a b c d
	//采用For Each输出集合
	for(String e:set){
		System.out.print(e+" ");
	}
	System.out.println();
	//输出:a b c d
	//采用toString输出集合
	System.out.println(set);
}	//输出:[a,b,c,d]
}
ArrayList 代码

import java.util.*;
import java.util.ArrayList;

/*time:2016-7-26 15:53:25
 * location:home
 * */
public class ArrayListDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<String> arrList = new ArrayList<String>();
		
		
		arrList.add("a");
		arrList.add("b");
		arrList.add("c");
		arrList.add("c");
		arrList.add("d");
		
		Iterator<String> iter = arrList.iterator();
		while(iter.hasNext()){
			System.out.print(iter.next()+" ");
		}
		System.out.println();
		//输出:a b c c d
		
		//For Each
		for(String arrl:arrList){
			System.out.print(arrl + " ");
		}
		System.out.println();
		//输出:a b c c d
	
		//直接输出
		System.out.println(arrList);
	}
}

Map代码

import java.nio.charset.MalformedInputException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
		map.put(1, 90);
		map.put(2, 95);
		map.put(17, 85);
		//1.通过键值查找遍历
		System.out.println(map.get(1));
		System.out.println(map.get(2));
		System.out.println(map.get(17));
		System.out.println(map.get(null));
		
		//2.在for-each循环中使用entries遍历
		for(Map.Entry<Integer, Integer> entry : map.entrySet()){
			System.out.println("Key = " + entry.getKey() + "value = " + entry.getValue());
		} 
		
		//3.在for-each循环遍历中keys或values
		for(Integer key : map.keySet()){
			System.out.println("key = " + key);
		}
		for(Integer value : map.values()){
			System.out.println("values = " + value);
		}
		
		//4.使用Iterator()遍历
		Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
		while(entries.hasNext()){
			Map.Entry<Integer, Integer> entry = entries.next();
			System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
		}
		
	}

}



参考链接:http://wenku.baidu.com/link?url=czkQnBS1dQ2CeX8TlR-1S-3PKLtmn1BED1_26Flnxa2v16U3-7zgDX78BTTe_YTgoX2FzlmQH_nhxLy3mqJ7XfAbf86iXi5A1ikNcEX8gD7

http://www.cnblogs.com/xwdreamer/archive/2012/05/30/2526822.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值