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
Set
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
自己写了个程序统计一段字符串中各个单词出现的次数。
/*
统计一段英文文本中单词出现的次数
打印结果格式: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
public static
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
public static
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。
可以创建一个刚刚好的数组,这样最优。
集合变数组的意义在于,可以限定对元素的操作(防止对数组的增删)。