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<? extends K, ? extends V>), 将整个指定集合插入到当前集合。

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<V> values(), 获取映射中值的Collection视图。
Set<K> keySet(), 返回映射中键的set视图。
Set<May.Entry<K,V>> 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<K,V>>,映射关系的数据类型是Map.Entry,带泛型。
Map.Entry<K,V>是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<String,Integer> tm=new TreeMap<String,Integer>();//定义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<Map.Entry<String,Integer>> entryS=tm.entrySet();
		Iterator<Map.Entry<String,Integer>> it=entryS.iterator();
		while(it.hasNext()){
			Map.Entry<String, Integer> 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 <T extends Comparable<? super T>> void sort(List<T> list), 按List集合元素自然顺序排序。
public static <T> void sort(Litst<T> list, Comparator<T> 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<String> list=new ArrayList<String>();
		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<String>{
	public int compare(String s1,String s2){
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()<s2.length())
			return -1;
		return s1.compareTo(s2);
	}
}
运行结果:
原集合:[adbd, sklg, oirbb, aaa, be, aaaa]
按String字符串自然顺序排序:[aaa, aaaa, adbd, be, oirbb, sklg]
按字符串长度排序:[be, aaa, aaaa, adbd, sklg, oirbb]

2. 获取最值
public static <T extends Object&Comparable<? super T>> T max(Collection<? extends T> coll), 按元素自然顺序取最大值。
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> 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<String> list=new ArrayList<String>();
		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<String> 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<String>{
	public int compare(String s1,String s2){
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()<s2.length())
			return -1;
		return s1.compareTo(s2);
	}
}
/*运行结果:
原集合:[adbd, sklg, oirbb, aaa, be, aaaa]
按String字符串自然顺序排序:[aaa, aaaa, adbd, be, oirbb, sklg]
按字符串长度排序:[be, aaa, aaaa, adbd, sklg, oirbb]
按String字符串自然顺序最靠后的:sklg
最长的字符串:oirbb
按字符串自然顺序fefdd的插入点是:4
按字符串长度顺序fefdd的插入点是:5
==================================
原集合:[be, aaa, aaaa, adbd, sklg, oirbb]
反转后的集合:[oirbb, sklg, adbd, aaaa, aaa, be]
替换一个元素后的集合:[oirbb, sklg, adbd, aaaa, aaa, beb]
集合中元素全部替换成abc: [abc, abc, abc, abc, abc, abc]
最初的list对象内容也变了:[abc, abc, abc, abc, abc, abc]*/

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<String> ts=new TreeSet<String>();//按字母顺序排序,[aaa, abcde, cc, k]
		//TreeSet<String> ts=new TreeSet<String>(Collections.reverseOrder());//按字母反向顺序排序, [k, cc, abcde, aaa]
		//TreeSet<String> ts=new TreeSet<String>(new StrLenComparator());//按字符串长度从小到大排序, [k, cc, aaa, abcde]
		TreeSet<String> ts=new TreeSet<String>(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。
可以创建一个刚刚好的数组,这样最优。
集合变数组的意义在于,可以限定对元素的操作(防止对数组的增删)。




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值