java集合(下)_Map集合

文章中总结了java Collection单列集合知识,本文接着描述java中的双列集合-Map集合,及java集合框架的2个常用工具类-Collections和Arrays。

Map集合
Map是java双列集合的顶层接口,Map集合中存储键值对,且键值唯一,双列集合中存储的也是对象的引用。
当数据之间存在着映射关系时,优先考虑使用Map集合。

Map接口常用方法
1. 添加
V put(K key, V value), 原集合中没有key值时,插入键值对(key,value), 返回null,  原集合中有key值时,新value值覆盖旧值,并返回旧值。
void put(Map), 将整个指定集合插入到当前集合。

2. 删除
void clear(), 清空集合
V remove(Object key), 原集合中有key值时,删除并返回该key对应的value值,原集合中没有key值时,返回null.

3. 判断
boolean containsKey(Object key), 判断集合中是否包含键值key.
boolean containsValue(Object value), 判断集合中是否包含指定value值
boolean isEmpty(), 判断集合是否为空。

4. 获取
V get(Object key), 如果集合中没有key键,返回null.
int size(), 返回集合长度
Collection values(), 获取映射中值的Collection视图。
Set keySet(), 返回映射中键的set视图。
Set> entrySet, 返回映射中映射关系的Set视图。

Map集合3个常用子类:Hashtable, HashMap, TreeMap.
Hashtable: 底层是哈希表数据结构,键和值都不能是null, 线程同步,从jdk1.0开始就有;作为键的对象必须实现hashCode()和equals()方法。

HashMap: 底层是哈希表数据结构,允许使用null值和null键, 线程不同步,从jdk1.2开始有,效率高,优先使用。
    LinkedHashMap:HashMap的子类,键值是有顺序的,取出顺序与存入顺序相同。

TreeMap: 底层是二叉树结构,线程不同步,可以对键排序,对键的排序方法与TreeSet基本一样,可以使用键对象的自然排序,也可以让TreeMap自身具备比较性(例子?)。

Map和Set很像,其实Set底层就是使用了Map(不太明白,先记录在这)。

Map集合的2种取出方式

Map集合没有迭代器,而Collection集合中有迭代器,所以只要将Map集合转成Set集合,就可以使用迭代器了。
1. keySet(), 将map中所有的键存入到Set集合中,而Set具备迭代器,所以可以通过迭代方式取出所有的键,再根据get(key)方法获取每个键对应的值。

2. entrySet(), 返回映射关系的Set集合,返回值类型是Set>,映射关系的数据类型是Map.Entry,带泛型。
Map.Entry是Map接口的嵌套内部static接口,该接口中有方法getKey()和getValue()可以取出键和值。

自己写了个程序统计一段字符串中各个单词出现的次数。

/*
 统计一段英文文本中单词出现的次数
打印结果格式:word(1)you(2)...
 */
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TreeMapDemo1 {
	public static void main(String[] args) {
		String s="i am a student, i have no money!";
		System.out.println(countWord(s));
	}
	public static String countWord(String str){		
		String regex="[A-Za-z0-9]+";//正则表达式,用字符串str去匹配regex,就得到所有单词
		Pattern p=Pattern.compile(regex);//将正则表达式封装成对象
		Matcher m=p.matcher(str);//将正则对象与要作用的字符串相关联,获取匹配器对象
		TreeMap tm=new TreeMap();//定义TreeMap,存放各个单词及出现的次数
		int count=0;//count最好是定义在while循环外面。
		while(m.find()){//字符串是否还有匹配regex的下一个子串
			Integer value=tm.get(m.group());//m.group()就是匹配得到的子串
			if(value!=null)
				count=value;
			count++;//count自增1是必须要执行的
			tm.put(m.group(),count);
			count=0;//
		}
		//下面让tm按打印要求输出。
		StringBuffer sb=new StringBuffer();
		Set> entryS=tm.entrySet();
		Iterator> it=entryS.iterator();
		while(it.hasNext()){
			Map.Entry me=it.next();
			String ss=me.getKey();
			Integer value=me.getValue();
			sb.append(ss+"("+value+")");
		}
		return sb.toString();
	}

}
运行结果:
a(1)am(1)have(1)i(2)money(1)no(1)student(1)

Map扩展:Map被使用是因为具有映射关系,映射关系中的值也可以是一个集合,如List集合、HashMap集合。

集合框架的工具类-Collections和Arrays

Collections类
该类的方法都是静态的,专门用于对集合对象的操作。

1. 对List集合排序
public staic > void sort(List list), 按List集合元素自然顺序排序。
public static void sort(Litst list, Comparator comp), 按指定的比较器排序。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CollectionsDemo {
	public static void main(String[] args) {
		sortDemo();
	}
	public static void sortDemo(){
		List list=new ArrayList();
		list.add("adbd");
		list.add("sklg");
		list.add("oirbb");
		list.add("aaa");
		list.add("be");
		list.add("aaaa");
		sop("原集合:"+list);
		Collections.sort(list);//按String字符串自然顺序排序。
		sop("按String字符串自然顺序排序:"+list);
		Collections.sort(list,new StrLenComparator());//按字符串长度排序
		sop("按字符串长度排序:"+list);
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
class StrLenComparator implements Comparator{
	public int compare(String s1,String s2){
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()

2. 获取最值
public static > T max(Collection coll), 按元素自然顺序取最大值。
public static T max(Collection coll, Comparator comp), 按比较器取最大值。

3. 二分法查找
int binarySearch(list,key), 如果搜索键包含在列表中,返回搜索键的索引,否则返回(-(键在列表的插入点)-1)。
int binarySearch(list,key,comp),同上,是按comp比较器查找和定位元素的插入点。
实际形式上类似于排序与最值方法,也带泛型,这里不再写了。

4. 替换反转
void fill(list,obj), 将list中全部元素替换成指定元素
boolean replaceAll(list, oldVaule, newValue), 方法里面实际封装了List接口的set(index,element)方法。
void reverse(list), 反转集合。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CollectionsDemo1 {
	public static void main(String[] args) {
		methodDemo();
	}
	public static void methodDemo(){
		List list=new ArrayList();
		list.add("adbd");
		list.add("sklg");
		list.add("oirbb");
		list.add("aaa");
		list.add("be");
		list.add("aaaa");
		sop("原集合:"+list);
		Collections.sort(list);//按String字符串自然顺序排序。
		sop("按String字符串自然顺序排序:"+list);
		Collections.sort(list,new StrLenComparator());//按字符串长度排序
		sop("按字符串长度排序:"+list);
		sop("按String字符串自然顺序最靠后的:"+Collections.max(list));//按字符串自然顺序取最大值
		sop("最长的字符串:"+Collections.max(list,new StrLenComparator()));//获取最长的字符串
		sop("按字符串自然顺序fefdd的插入点是:"+(-Collections.binarySearch(list, "fefdd")-1));
		sop("按字符串长度顺序fefdd的插入点是:"+(-Collections.binarySearch(list, "fefdd",new StrLenComparator())-1));
		System.out.println("==================================");
		List list2=list;
		sop("原集合:"+list2);
		Collections.reverse(list2);
		sop("反转后的集合:"+list2);
		Collections.replaceAll(list2, "be", "beb");
		sop("替换一个元素后的集合:"+list2);
		Collections.fill(list2, "abc");
		sop("集合中元素全部替换成abc: "+list2);
		sop("最初的list对象内容也变了:"+list);
		
		
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
class StrLenComparator implements Comparator{
	public int compare(String s1,String s2){
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()

5. 逆转比较器
Comparator reverseOrder()

import java.util.Collections;
import java.util.TreeSet;
public class CollectionsDemo2 {
	public static void main(String[] args) {
		orderDemo();
	}
	public static void orderDemo(){
		//TreeSet ts=new TreeSet();//按字母顺序排序,[aaa, abcde, cc, k]
		//TreeSet ts=new TreeSet(Collections.reverseOrder());//按字母反向顺序排序, [k, cc, abcde, aaa]
		//TreeSet ts=new TreeSet(new StrLenComparator());//按字符串长度从小到大排序, [k, cc, aaa, abcde]
		TreeSet ts=new TreeSet(Collections.reverseOrder(new StrLenComparator()));//按字符串长度从大到小排序, [abcde, aaa, cc, k]		
		ts.add("abcde");
		ts.add("aaa");
		ts.add("k");
		ts.add("cc");
		CollectionsDemo1.sop(ts);
	}
}

6. 获取线程安全的集合
List sychronizedList(list), 原理是在List的remove(), add()等方法中加锁,且是同一个锁,代码都放在同步代码块中。

7. 置换
void swap(list, index1, index2)
void shuffle(list), 将集合元素随机排放,相当于洗牌。

Arrays类
用于操作数组的工具类,里面都是静态方法。其中大量方法可以直接查阅API文档,这里特别介绍下面三个。

1. Arrays.toString()
返回数组的字符串形式,如将整型数组 arr{2,3,4},打印成[2,3,4].

2. Arrays.asList(), 数组转成List集合
好处: 可以使用集合的思想和方法来操作数组中的元素,如判断contain(),获取(get(), indexOf), subList()等.
注:将数组变成集合,不可以使用集合的增删方法(会报UnsupportedOperationException),因为数组的长度固定。
如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
如果数组中的元素都是基本数据类型,则会将整个数组用为集合中的元素存在。

3. 集合变数组
使用Collection接口中的toArray()方法:T[] toArray(T[] t)。
当指定类型的数组长度小于了集合的size, toArrays()方法内部创建一个新的数组,长度为集合的size;
如果数组长度大于集合的size, 就不会再创建新数组, 而是直接使用传递进来的数组,多余的位置上值为null。
可以创建一个刚刚好的数组,这样最优。
集合变数组的意义在于,可以限定对元素的操作(防止对数组的增删)。





你可能感兴趣的:(java基础)