java集合-Map

Map集合不继承Collection,Map是映射键值对,存储对象的时候,一次性存储两个对象,一个作为键(K),一个作为值(V)。

区别:

Collection一个对象存储方式是add

Map 两个对象存储方式 put()

Map集合中,不能出现重复键,每一个键最多只能映射一个值,但是不同键可以有相同值

一、Map中的方法

直接上demo

package map;
/*
 * Map中的方法
 */
import java.util.*;
public class MapDemo {
    public static void main(String[] args) {
        /*method1();
        method2();
        method3();
        method4();*/
        method5();
    }
    /*
     * put(k,v)将键值存储到集合中
     */
    public static void method(){
        Map<String,Integer> map = new HashMap<>();
        map.put("a", 1);
        map.put("b", 1);
        map.put("c", 1);
        map.put("d", 4);
        map.put("e", 6);
        System.out.println(map);
    }
    
    /*
     * putAll(Map map)把一个集合全部插入另一个集合
     * 
     */
    public static void method1(){
        Map<String,Integer> map = new HashMap<>();
        map.put("a", 1);
        map.put("b", 1);
        map.put("c", 1);
        
        Map<String,Integer> map2 = new HashMap<>();
        map2.put("e", 2);
        map2.put("f", 3);
        map2.put("g", 4);
        
        map.putAll(map2);

        System.out.println(map);
    }
    
    /*
     * V get(Key) 传递一个键,返回键对应的值,如果此键不存在,返回为空
     */
    public static void method2(){
        Map<String,Integer> map = new HashMap<>();
        map.put("a", 234);
        map.put("b", 1);
        map.put("c", 1);
        System.out.println(map.get("z"));
    }
 
    /*
     * void clear() 清除所有对象
     * void isEmpty() 判断是为空
     * int size() 返回映射关系对的个数
     * boolean containsKey(Key) 判断键是否存在,存在返回真,否则返回假
     * boolean containsValue(Value) 同理判断值是否存在,存在返回真,不存在返回假
     */
    public static void method3(){
            Map<String,Integer> map = new HashMap<>();
            map.put("a", 1);
            map.put("b", 123);
            map.put("c", 124);
            System.out.println(map.size());
            System.out.println(map.containsKey("A"));
            //自动装箱,会调用equals判断,所以为真
            System.out.println(map.containsValue(new Integer(124)));
            map.clear();
            System.out.println(map.isEmpty());
    }
  
    /*
     * V remove(K)
     * 移除指定的键值对,传递键,返回值
     * 没有移除成功返回null
     */
    public static void method4(){
        Map<String,Integer> map = new HashMap<>();
        map.put("a", 1);
        map.put("b", 123);
        map.put("c", 124);
        System.out.println(map.remove("a"));
        System.out.println(map);
    }
  
    /*
     * Collection<V> values()将Map中的所有值,存储到Collection集合
     */
    public static void method5(){
        Map<String,Integer> map = new HashMap<>();
        map.put("a", 1);
        map.put("b", 123);
        map.put("c", 124);
        
        Collection<Integer> c = new ArrayList<>();
        
        c = map.values();
        System.out.println(map);
        System.out.println(c);
    }
    
}

二、Map集合的取出方法

遍历Map集合有两种方法,一种是利用set集合遍历,另外一种是利用内部类原理进行遍历。

Demo

package map;

import java.util.*;

public class MapDemo1 {
    /*
     * 练习map的两种数据取出方式
     */
    public static void main(String[] args) {
        method1();
    }
    
    /*
     * 利用set取出
     */
    public static void method(){
        Map<String, Integer> map = new HashMap<>();
        
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        map.put("d",4);

        Set<String> set = map.keySet();
        
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            System.out.println(map.get(it.next()));
        }
    }
    
    /*
     * 利用集合的键值对关系对象获取 entrySet,这是一个内部类
     */
    public static void method1(){
        Map<String, Integer> map = new HashMap<>();
        
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        map.put("d",4);
        
        Set<Map.Entry<String, Integer>> o = new HashSet<>();
        
        o = map.entrySet();
        
        Iterator<Map.Entry<String, Integer>> it = o.iterator();
        
        while(it.hasNext()){
            //利用多态,next返回实现类对象给接口,可以不用管具体的实现类原理
            Map.Entry<String, Integer> entry = it.next();
            
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }       
    }
}

三、增强for循环间接遍历map

实现的原理其实和上面的set遍历相似,因为map小的小弟们没有实现接口Iterable,所有不能使用增强for循环,因此map也就没有办法使用增强for循环来遍历了。所以,借助Key的set集合来使用for循环,从而间接遍历可以获取到map集合中的数据,同样,这种方式也可以和map的取出方法一样,有两种写法。

demo

package map;
/*
 * for循环遍历间接遍历map
 */
import java.util.*;

public class MapDemo2 {
    public static void main(String[] args) {
        
        Map<String, Integer> m = new HashMap<>();
        m.put("a", 1); 
        m.put("b", 2); 
        m.put("c", 3);
        
      //1.利用普通的set方法for循环遍历,平时中推荐使用
        /*for(String s : m.keySet()){
            System.out.println(s+"----" +  m.get(s));
        }*/
    //2.同样,使用内部类来进行实现   
        for(Map.Entry<String, Integer> entry : m.entrySet()){
            System.out.println(entry.getKey() + "..."+  entry.getValue());
        }
    }
}

四、HashMap类

基于哈希表的映射键值对,线程不安全,可以存储null值和null键,没有顺序。要求键是唯一的,对象必须重写hashCode方法和equals方法。

demo

package map;
/*
 * HashMap集合的存取自定义对象
 * Person是之前自定义的对象
 */

import SetDemo.Person;
import java.util.*;

public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<Person,String> hm = new HashMap<>();
        
        hm.put(new Person("张三",22), "加拿大");
        hm.put(new Person("李四",42), "澳大利亚");
        hm.put(new Person("王五",71), "美国");
        hm.put(new Person("赵六",54), "英国");
        
        method1(hm);
    }
    
    /*
     * 实现map集合的第一种获取方法
     */
    public static void method(HashMap<Person,String> hm){
        
        Set<Person> set  = hm.keySet();
        
        Iterator<Person> it = set.iterator();
        
        while(it.hasNext()){
            Person p = it.next();
            
            String s = hm.get(p);
            
            System.out.println(p + ".." + s);
        }
    }
    
    /* 
     * 第二种方法获取,entry
     */
    public static void method1(HashMap<Person,String> hm){
        
        Set<Map.Entry<Person, String>> set = hm.entrySet();
        
        Iterator<Map.Entry<Person, String>> it = set.iterator();
        
        while(it.hasNext()){
            Map.Entry<Person, String> e = it.next();
            
            System.out.println(e.getKey() + ".." + e.getValue());
        }       
    }   
}

五、LinkedMap类

LinkedMap是HashMap的子类,基于链表的哈希表实现,有序的Map集合,线程不安全的,开始版本于JDK1.4。

package map;
import java.util.*;
/*
 * LinkedHashMap的存储和遍历
 * 按put的顺序排序
 */

public class LinkedHashMapDemo {
    public static void main(String[] args) {
        LinkedHashMap<String, String> lhm = new LinkedHashMap<>();
        
        lhm.put("a","65" );
        lhm.put("c","67" );
        lhm.put("b","668" );
        lhm.put("A","786" );
        lhm.put("d","786786" );
        
        for(String key : lhm.keySet()){
            System.out.println(lhm.get(key));
        }
    }
}

六、HashTable

底层数据结构也是哈希表,但是不允许存储null,线程安全,运行速度慢。开始版本JDK1.0,没有集合框架以前,存储键值对,只能依靠Hashtable,被HashMap取代,郁郁而终了。但是他有一个子类Properties,依然活跃在开发舞台,这个集合可以和IO流配合使用。

七、TreeMap集合

对存储的键进行排序,需要对象的自然顺序,或者比较器,用法和实现代码,直接参考HashSet集合,线程不安全集合,运行速度快,底层实现红黑树,自然平衡算法二叉树。

package cn.itcast.map;
/*
 * TreeMap存储自定义对象
 * 提供两个排序方式,自然顺序,一个是比较器
 */
import java.util.*;
import SetDemo.PersonComparator;

public class TreeMapDemo {
    public static void main(String[] args) {
      //传递一个自然比较对象进去
        TreeMap<Person,String> tm = new TreeMap<Person, String>(new PersonComparator());
         tm.put(new Person("lisi",18), "加拿大");
         tm.put(new Person("zhangsa",17), "澳大利亚");
         tm.put(new Person("zhangsa",17), "澳大利亚");
         tm.put(new Person("wangwu",20), "新加坡");
         tm.put(new Person("zhaoliu",19), "新西兰");
         tm.put(new Person("zhaoliu",19), "新西兰");
         tm.put(new Person("lisa",22), "迪拜");
//       keySet(tm);
         entrySet(tm);
    }
    /*
     * 增强for循环,遍历entrySet方式
     */
    public static void entrySet(TreeMap<Person,String> hm){
        for(Map.Entry<Person, String> entry : hm.entrySet()){
            Person p = entry.getKey();
            String value = entry.getValue();
            System.out.println(p+"..."+value);
        }
    }
    
    /*
     * 增强for循环,遍历keySet方式
     */
    public static void keySet(TreeMap<Person,String> tm){
        for(Person p : tm.keySet()){
            String value = tm.get(p);
            System.out.println(p+"..."+value);
        }
    }
}

八、map集合的小练习

题目:统计一个字符串内每个字母出现的顺序,存储在集合之中

package map;

/*
 * 练习:
 * 统计字符串里面每个字符出现的次数,存储到map里面
 * eg:a=1,b=3....
 * 
 */
import java.util.*;
public class HashMapTest {
    public static void main(String[] args) {
        String s = "xcvgbjhmklfdxhkuxck.jbjgcj,ckyfxckh";

        System.out.println(method(s));
    }
     
    public static Map<Character,Integer> method(String s){
        char[] c = s.toCharArray();
        
        Map<Character,Integer> tongji = new HashMap<Character, Integer>();
        
        for(int i = 0 ; i < c.length ; i++){
            char temp = c[i];
            if(tongji.containsKey(temp)){
                
                tongji.put(temp,tongji.get(temp)+1);
            }
            else{
                tongji.put(temp, 1);
            }
        }
        return tongji;
    }
}

九、Properties类

Hashtable的子类,也是一个线程安全的键值对的集合。这个类不同于其他集合,可以和IO流结合使用,实现数据的永久性存储。查看API发现这个集合没定义泛型,泛型已经被设定好了,键值对的数据类型都是字符串,完全适用于Map中的一切操作。

特有方法setProperty(String key,String value)等同于就是Map中的put,getProperty(String value)传递键,返回对应的值,等同于Map中的get方法, 以后可以用于配置文件。

demo

package map;

/*
 * Properties类的练习
 */

import java.util.*;

public class PropertiesDemo {
    public static void main(String[] args) {
        method1();
        
        Properties pro = System.getProperties();
        
        System.out.println(pro);
        
        System.out.println(pro.get("os.name"));
        
    }
    
    /*
     * 使用Properties自己的方法操作
     */
    public static void method1(){
        Properties pro = new Properties();
        pro.setProperty("a", "1");
        pro.setProperty("b", "2");
        pro.setProperty("c", "3");
        pro.setProperty("d", "4");
        pro.setProperty("e", "5");
        
        System.out.println(pro.getProperty("a"));
        System.out.println(pro.getProperty("bb"));

    }
    
    /*
     * 像map一样操作Properties
     */
    public static void method(){
        Properties pro = new Properties();
        pro.put(1, 321);
        pro.put(2, 345321);
        pro.put(3, 321);
        pro.put(5, 321);
        pro.put(4, 324534531);
    
        
        System.out.println(pro.get(3));
        
        Set set = pro.keySet();
        
        Iterator it = set.iterator();
        
        while(it.hasNext()){
            Object key = it.next();
            Object value = pro.get(key);
            
            System.out.println(key + "..." + value);
        }
    }
}

十、Collections工具类

Collections中的方法都是静态的,用于操作集合类的。

  • static void sort(List list)根据存储在集合的对象的自然顺序,对List集合排序
  • static void sort(List list,Comparator com)根据比较器对List集合排序
  • static Comparator reverseOrder()返回比较器,逆转对象的自然顺序
  • static Comparator reverseOrder(Comparatorc)传递比较器,返回比较器,返回的比较器逆转了传递的比较器
  • static int binarySearch(List list, Objectkey)集合的折半查找,传递List集合必须有序,找到返回下标,找不到返回,返回插入点-1
  • static void fill(List list,Object obj)填充集合
  • static void swap(List list ,int x,int y)指定下标,对List集合中的对象换位置
  • static void shuffle(List list)对List集合中的对象,随机换位置
  • 将线程不安全集合变成线程安全集合 synchronized开头的方法
package Collections;

/*
 * 集合工具类的操作方法
 */
import java.util.*;

import SetDemo.Person;
import SetDemo.PersonComparator;

public class CollectionsDemo {
    public static void main(String[] args) {

        method_4();

    }

    /*
     * static void swap(List list ,int x,int y)指定下标,对List集合中的对象换位置 static void
     * shuffle(List list)对List集合中的对象,随机换位置
     */
    public static void method_4() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(8);

        System.out.println(list);
        Collections.swap(list, 0, 1);
        System.out.println(list);

        Collections.shuffle(list);
        System.out.println(list);
    }

    /*
     * static void fill(List list,Object obj)填充集合
     */
    public static void method_3() {
        List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(13);
        list.add(15);
        list.add(78);
        list.add(54);

        Collections.fill(list, 2);
        System.out.println(list);
    }

    /*
     * static int binarySort(List list)集合的折半查找折半查找,
     */
    public static void method_2() {
        List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(13);
        list.add(15);
        list.add(78);
        list.add(54);
        list.add(84);
        list.add(25);
        list.add(65);

        int i = Collections.binarySearch(list, 84);

        System.out.println(i);
    }

    /*
     * static Comparator reverseOrder()返回比较器,逆转对象的自然顺序 static Comparator
     * reverseOrder(Comparatorc)传递比较器,返回比较器,返回的比较器逆转了传递的比较器
     *
     */
    public static void method_1() {
        List<Person> list = new ArrayList<>();

        list.add(new Person("liu", 23));
        list.add(new Person("niu", 21));
        list.add(new Person("fei", 222));
        list.add(new Person("zi", 2323));

        Collections.sort(list, Collections.reverseOrder(new PersonComparator()));

        System.out.println(list);
    }

    /*
     * static void sort(List list) 可以给集合排序 static void sort(List list,Comparator
     * com)根据比较器对List集合排序
     */
    public static void method() {
        List<String> list = new ArrayList<>();

        list.add("slkeghk");
        list.add("aftytyj");
        list.add("bturehk");
        list.add("crgresr");

        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);

        List<Person> l = new ArrayList<>();

        l.add(new Person("liu", 23));
        l.add(new Person("niu", 21));
        l.add(new Person("fei", 222));
        l.add(new Person("zi", 2323));

        System.out.println(l);
        Collections.sort(l);
        System.out.println(l);
    }
}

十一、集合数组的互转

数组转成集合 Arrays类方法isList , 传递数组,返回集合。

数组转成集合后,改变集合长度的操作不能做,如果做了,出现不支持的操作异常

集合转数组Collection中方法toArray() 将集合转成数组,传递数组,返回数组

写法:list.toArray(new Object[list.size()]);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • Map(映射,存储的是“键-值”映射表,“键”是不能重复的) 如果键重复,则相当于修改对应键的值。 Map接口定义...
    向日花开阅读 6,190评论 0 3
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,488评论 0 3
  • 第十天 权限修饰符 public protected default private 同一类 true true ...
    炙冰阅读 534评论 0 1
  • iOS真机调试/发布app相关的设置 首先要更新你开发者账户中的Provisioning Profiles。 Xc...
    NapoleonY阅读 1,173评论 3 3