一、map集合
Map:一次添加一对元素。Collection 一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实map集合中存储的就是键值对(结婚证书), map集合中必须保证键的唯一性。
方法简介:
1、添加 put(K key, V value) 以键值对的形式往里存
putAll(Map<? extends K,? extends V> m) 把一个map里的内容作为值存入进map中。
2、删除 clear() 清空集合
remove(Object key) 清楚其中的一条
3、判断 containsValue(Object value) 判断map中是否包含某个值
containsKey(Object key) 判断map中是否包含某个值
isEmpty()判空
4、获取 get(Object key) 根据key获取值
size() 获取map集合的大小
注:
a、也可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。
b、其中put方法:如果出现添加相同的键,那么后添加的值会覆盖原有键对应的值,并且该方法返回被覆盖的值即原值。
class MapDemo
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
//添加元素,添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并返回以前的值,以前没值就放回null
System.out.println("put:"+map.put("01","zhangsan1"));
System.out.println("put:"+map.put("01","wnagwu"));
- map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println("containsKey:"+map.containsKey("022")); 判断
//System.out.println("remove:"+map.remove("02"));删除
System.out.println("get:"+map.get("023"));
map.put("04",null);
System.out.println("get:"+map.get("04"));
//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
//获取map集合中所有的值。
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map);
}
两种获取集合元素的方法:
1、keySet()方法获取元素
原理:将Map集合中的所有键存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
// Map<Integer,String> map = new HashMap<Integer,String>();
// map.put(8,"zhaoliu");
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");
//先获取map集合的所有键的Set集合,keySet();
Set<String> keySet (故意起的,有意义)= map.keySet();
//有了Set集合。就可以获取其迭代器。
Iterator<String> it = keySet.iterator();
while(it.hasNext())
{
String key = it.next();
//有了键可以通过map集合的get方法获取其对应的值。
String value = map.get(key);
System.out.println("key:"+key+",value:"+value);
}
}
}
2、entrySet()方法获取元素:
原理:将Map集合中的映射关系存入到了Set集合中,而这个映射关系的数据类型是Map.Entry(结婚证),在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()和getValue()放取出键值。
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");
//将Map集合中的映射关系取出。存入到Set集合中。
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrySet.iterator();
while(it.hasNext())
{
Map.Entry<String,String> me = it.next();
String key = me.getKey();
String value = me.getValue();
System.out.println(key+":"+value);
}
}
}
补充:关于<Map.Entry<String,String>>
Map是一个接口,其实,Entry也是一个接口,它是Map的子接口中的一个内部接口,就相当于是类中有内部类一样。为何要定义在其内部呢?
原因:
a.Map集合中存的是映射关系这样的两个数据,是先有Map这个集合,才可有映射关系的存在,而且此类关系是集合的内部事务。
b.并且这个映射关系可以直接访问Map集合中的内部成员,所以定义在内部。
3、只获取姓名,可以用下面得的,当然可以用上面的:
Map常用的子类:
|--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。 //最先出来
|--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
|--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。
|--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。
注:Set底层就是使用了Map集合。
演示1:
public class HashMapDemo {
public static void main(String[] args) {
/*
* 将学生对象和学生的归属地通过键与值存储到map集合中
*/
HashMap<Student,String> hm = new HashMap<Student,String>();
hm.put(new Student("lisi",38),"北京");
hm.put(new Student("zhaoliu",24),"上海");
hm.put(new Student("xiaoqiang",31),"沈阳");
hm.put(new Student("wangcai",28),"大连");
hm.put(new Student("zhaoliu",24),"铁岭");
? o1.getAge-o2.getAge:temp;}
}
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Student,String> tm = new TreeMap<Student,String>(new ComparatorByName());
tm.put(new Student("lisi",38),"北京");
tm.put(new Student("zhaoliu",24),"上海");
tm.put(new Student("xiaoqiang",31),"沈阳");
tm.put(new Student("wangcai",28),"大连");
tm.put(new Student("zhaoliu",24),"铁岭");
Iterator<Map.Entry<Student, String>> it = tm.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Student,String> me = it.next();
Student key = me.getKey();
String value = me.getValue();
System.out.println(key.getName()+":"+key.getAge()+"---"+value);
}
}
}
演示3:LinkedHashMap(有序),和LinkedHashSet使用一样
public class LinkedHashMapDemo {
public static void main(String[] args) {
HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>();
hm.put(7, "zhouqi");
hm.put(3, "zhangsan");
hm.put(1, "qianyi");
hm.put(5, "wangwu");
Iterator<Map.Entry<Integer,String>> it = hm.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer,String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+":"+value);
}
}
}
练习: 1
* "fdgavcbsacdfs" 获取该字符串中,每一个字母出现的次数。
* 要求打印结果是:a(2)b(1)...;
* 思路:
* 对于结果的分析发现,字母和次数之间存在着映射的关系。而且这种关系很多。
* 很多就需要存储,能存储映射关系的容器有数组和Map集合。
* 关系一方式有序编号吗?没有!
* 那就是使用Map集合。 又发现可以保证唯一性的一方具备着顺序如 a b c ...
* 所以可以使用TreeMap集合。
*
* 这个集合最终应该存储的是字母和次数的对应关系。
*
* 1,因为操作的是字符串中的字母,所以先将字符串变成字符数组。
* 2,遍历字符数组,用每一个字母作为键去查Map集合这个表。
* 如果该字母键不存在,就将该字母作为键 1作为值存储到map集合中。
* 如果该字母键存在,就将该字母键对应值取出并+1,在将该字母和+1后的值存储到map集合中,
* 键相同值会覆盖。这样就记录住了该字母的次数.
* 3,遍历结束,map集合就记录所有字母的出现的次数。
class MapTest1
{
public static void main(String[] args)
{
String s= charCount("ak+abAf1c,dCkaAbc-defa"); //返回一个新的字符串结果
System.out.println(s);
}
public static String charCount(String str)
{ //将字符串变成字符数组
char[] chs = str.toCharArray();
//定义map集合表。
Map<Character,Integer> tm = new TreeMap<Character,Integer>();
//因为只存取,不需要TreeMap的特有方法,将他提升为map就可以
for(int x=0; x<chs.length; x++)
{
if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z'))
continue;
//将数组中的字母作为键去查map表。
Integer value = tm.get(chs[x]); //直接作为键去查表
int count = 1; //计数器
//判断值是否为null.
if(value!=null){
count = value+1; //用个变量记录下
}
// count++;
map.put(chs[i], count);
/* //这种比较麻烦
if(value==null){
map.put(chs[i], 1);
}else{
map.put(chs[i], value+1); //直接往集合中存储字符和数字,为什么可以,因为自动装箱
}
*/
}
}
//System.out.println(tm);
// 上边已经解决,转换它的那种结果a(2)b(1).
return mapToString(map);
}
private static String mapToString(Map<Character, Integer> map) {
StringBuilder sb = new StringBuilder();
Iterator<Character> it = map.keySet().iterator();
while(it.hasNext()){
Character key = it.next();
Integer value = map.get(key);
sb.append(key+"("+value+")");
}
return sb.toString();
}
}
练习2:
map什么时候用, Map在有映射关系时,可以优先考虑。在查表法中的应用较为多见。
public class MapTest2 {
public static void main(String[] args) {
String week = getWeek(1); //查表
System.out.println(week);
System.out.println(getWeekByMap(week));
}
public static String getWeekByMap(String week){
Map<String,String> map = new HashMap<String,String>();
map.put("星期一","Mon");
map.put("星期二","Tus");
map.put("星期三","Wes");
map.put("星期日","Sun");
map.put("星期天","Sun");
return map.get(week);
}
public static String getWeek(int week){
if(week<1 || week>7)
throw new RuntimeException("没有对应的星期,请您重新输入");
String[] weeks = {"","星期一","星期二"};
return weeks[week];
}
}
第二:Collections工具类
Collections和Collection有什么区别?
- Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。
- Collections ? o1.compareTo(o2) : temp;
}
}
- Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。
- Collections ? o1.compareTo(o2) : temp;
}
}
Set:不可以重复元素。无序。
- Collections ? o1.compareTo(o2) : temp;
}
}
源码: Collections.sort(list,new ComparatorByLength())的排序原理
public static <T> void mySort(List<T> list,Comparator<? super T> comp){
for (int i = 0; i < list.size()-1; i++) {
for (int j = i+1; j < list.size(); j++) {
if(comp.compare(list.get(i), list.get(j))>0){
// T temp = list.get(i);
// list.set(i, list.get(j));
// list.set(j, temp);
Collections.swap(list, i, j);
}
}
}
源码: Collections.sort(list)的排序原理
public static <T extends Comparable<? super T>> void mySort(List<T> list){ 长度比较
//<T extends Comparable<? super T>>需要限定,继承
; i < list.size()-1; i++) {for (int j = i+1; j < list.size(); j++) {
if(list.get(i).compareTo(list.get(j))>0){
Collections.swap(list, i, j);
public static void demo_2(){二分查找、最值
List<String> list = new ArrayList<String>();
list.add("abcde");
list.add("cba");
list.add("aa");
list.add("zzz");
list.add("cba");
list.add("nbaa");
// Collections.sort(list); 没顺序不能折半,先排序
System.out.println(list);