欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java基础第十四篇之Map

程序员文章站 2022-10-04 14:52:10
一,Map集合的特点: * * 1.Map集合和Collection集合,没有关系 * * 2.Map集合的元素是成对存在(夫妻关系) * Collection集合的元素是独立存在的(单身关系) * * 3.Map集合的元素不能重复(是元素的key值不能重复) * * 总结: * Collectio ......


 一,map集合的特点:
 * 
 * 1.map集合和collection集合,没有关系
 * 
 * 2.map集合的元素是成对存在(夫妻关系)
 *         collection集合的元素是独立存在的(单身关系)
 * 
 * 3.map集合的元素不能重复(是元素的key值不能重复)
 * 
 * 总结:
 *         collection集合我们一般称为单列集合
 *         map集合我们称为双列集合
 * 二,map接口下常用的实现类
 * 
 * hashmap<k,v>:底层是哈希表结构,无序的(存取顺序不一致)
 * 
 * 
 * linkedhashmap<k,v>:底层链表+哈希表结构,有序的(存取顺序一致)
 *             这里<k,v>是两个泛型,这里的k和v可以相同 也可以不同
 *             k代表键的类型,v代表的是值的类型
 * 
 * 以上所有的实现类,保证键的唯一性(键不能重复),那么我们需要重写k这种类型的hashcode和equals方法
 *         比如:k的类型是string,integer...(java提供的类型),那么我们不需要管他
 *             k的类型是person,dog等自定义类型 那么我们就需要重写hashcode和equals方法
 * 
 * 三,map接口中定义的常用方法:
 * 
 * 1.增加:
 *         public v put(k key,v value);//向map集合中添加一个元素(键值对)
 *         返回值:表示被新的键值对 覆盖的那个旧的键值对的值
 *             如果没有覆盖,返回值是null
 * 
 * 2.删除:
 *         public v remove(object key);//删除一个键值对(根据键来删除)
 * 
 * 3.改:实际上就是put方法,只要put的时候键和map集合中原有的键重复,就可以达到改的目的
 * 
 * 4.查
 *         public v get(object key);//根据键 来查找键所对应的值
 
 
 public interface interfacea {
    public abstract void showa();
    
    interface interfaceb{//内部接口
        public abstract void showb();
    }
}

//定义一个类 去实现接口

class myclass1 implements interfacea{

    @override
    public void showa() {
        // todo auto-generated method stub
        
    }

//    @override
//    public void showa() {
//        // todo auto-generated method stub
//        
//    }
}

class myclass2 implements interfacea.interfaceb{

    @override
    public void showb() {
        // todo auto-generated method stub
        
    }
    
}


/*
 * 1.因为map集合 和collection集合 没有继承关系
 *      map集合中是没有迭代器
 *  
 * 2.java为map集合提供了另外两种迭代的方式:
 *         方式一:以键找值的方法:
 *             获取所有的键的集合 map.keyset();
 *         方式二:键值对的方式
 *             public set<map.entry<k,v>> entryset()
 */
 
 //创建内部类对象
        //outerclass.innerclass oi = new outerclass().new innerclass();
        map<string, integer> map = new hashmap<string, integer>();
        map.put("张三", 18);
        map.put("李四", 28);
        map.put("王五", 38);
        map.put("赵六", 48);
        //1.获取map集合的entry 集合
        set<map.entry<string, integer>> entries = map.entryset();
        //2.用迭代器 遍历这个entries这个set集合
        iterator<map.entry<string, integer>> it = entries.iterator();
        //3.遍历
        while(it.hasnext()){
            map.entry<string, integer> entry = it.next();
            //一个entry中 有两个属性
            string key = entry.getkey();
            integer value = entry.getvalue();
            system.out.println(key+"="+value);
            
        }
        
 
 * 练习1:使用map存储:键为学号,值为一个学生的对象,学生对象有属性(姓名,年龄)
 * 
 * 
 * 练习2:使用map存储:键为学生(姓名,年龄)值为学生自己的家庭住址。
 *         map<student,string>
 
 public class mapdemo {
    public static void main(string[] args) {
        //定义一个map集合 存储键为学生(姓名,年龄)值为学生自己的家庭住址。
        map<student, string> map = new hashmap<student, string>();
        //向集合添加数据
        map.put(new student("王宝强", 40), "北京五环外");
        map.put(new student("谢霆锋", 50), "北京180环外");
        map.put(new student("马蓉", 45), "上海交通路");
        map.put(new student("郭德纲", 55), "广州德云社");
        map.put(new student("马蓉", 45), "我家");
        //map判断键重复不重复,是通过hashcode和equals方法
        //如果 我要求一个学生的姓名和年龄一样 就认为是同一个学生
        //遍历集合 keyset entryset
        //1.获取entry的集合
        set<map.entry<student, string>> entries = map.entryset();
        //2.迭代器遍历 foreach
        for (map.entry<student, string> entry : entries) {
            student key = entry.getkey();
            string value = entry.getvalue();
            system.out.println(key+"="+value);
        }
    }
}


/*
 * linkedhashmap: 采用链表+哈希表结构
 *         元素是有序的
 
  collection和map都可以嵌套
 * 
 * arraylist<arraylist<string>>
 * 
 * arraylist<map<k,v>>
 * 
 * map<string,arraylist<string>>
 * 
 * map<string,map<string,student>>
 * 
 * 比如我们传智博客学生(有ios android ui javaee)
 *        map<学号,学生> ui = new hashmap<学号,学生>();
 *
 *        map<学号,学生> javaee = new hashmap<学号,学生>();
 *
 *        map<学号,学生> android = new hashmap<学号,学生>();
 *
 *        
 *         arraylist<map<学号,学生>>  al= new ....
 *             al.add(ui);
 *             al.add(javaee);
 *             al.add(android);
 * 
 *         map<学院名,map<学号,学生>> map = new ....
 *             map.put("ui学院",ui);
 *             map.put("javaee学院",javaee);
 *             map.put("安卓学院",android);
 * 
 *         
 * 
 * 
 * 
 */
public class mapmapdemo {

    public static void main(string[] args) {
        // todo auto-generated method stub
        //1.创建一个ui学院的map集合
        map<string, student> uimap = new hashmap<string, student>();
        uimap.put("黑马001", new student("小丽", 18));
        uimap.put("黑马003", new student("小美", 19));
        uimap.put("黑马004", new student("小雨", 20));
        //2.创建一个javaee学院map集合
        map<string, student> eemap = new hashmap<string, student>();
        eemap.put("黑马001", new student("小诗", 18));
        eemap.put("黑马002", new student("小公", 19));
        eemap.put("黑马004", new student("小龙", 20));
        //3.创建一个android学院map集合
        map<string, student> anmap = new hashmap<string, student>();
        anmap.put("黑马002", new student("小k", 18));
        anmap.put("黑马003", new student("小q", 19));
        anmap.put("黑马004", new student("小a", 20));
        //4.定义一个存储所有学院名字和map对象的集合
        map<string,map<string, student>> map = new hashmap<string, map<string,student>>();
        map.put("ui学院", uimap);
        map.put("ee学院", eemap);
        map.put("an学院", anmap);
        //遍历map 打印是每一个学生
        //1.keyset() 2.entryset()
        set<map.entry<string,map<string, student>>> entries = map.entryset();
        //2.遍历 entries 迭代器,foreach
        iterator<map.entry<string,map<string, student>>> it = entries.iterator();
        //标准代码
        while(it.hasnext()){
            map.entry<string,map<string, student>> entry = it.next();
            string key = entry.getkey();
            map<string, student> valuemap = entry.getvalue();
            //遍历value这个map集合 keyset entryset
            set<map.entry<string, student>>  xyentries = valuemap.entryset();
            //迭代器 foreach
            iterator<map.entry<string, student>> xyit = xyentries.iterator();
            //标准代码
            while(xyit.hasnext()){
                map.entry<string, student> xyentry = xyit.next();
                string xykey = xyentry.getkey();
                student xyvalue = xyentry.getvalue();
                //system.out.println("学院,学号,学生名字,学生年龄");
                system.out.println(key+"-"+xykey+"-"+xyvalue.getname()+"-"+xyvalue.getage());
            }
                
        }
        
        
        
        
    }

}


* collections集合工具类中的两个方法:
 * 
 * public static void sort(list<t> list);//按照自然顺序(123 321 abc cba)排序一个list集合
 * 
 * public static void shuffle(list<?> list);//打乱集合中顺序
 
 * 可变参数: 这里说的可变 不是参数的数据类型 而是参数的个数
 *         jdk1.5之后的新特性
 * 
 *         格式: public void shownum(int... num){
 * 
 *              }
 * 
 * 注意事项:
 *         当一个方法具有多个参数,而且其中有一个是可变参数,那么可变参数必须写到 参数的最后一个
 *     
 
 public class variableargdemo01 {

    public static void main(string[] args) {
        // todo auto-generated method stub
//        show(1);
//        show(1,2);
//        show(1,2,3);
        show(1,2,3,4,5);
    }
    //定义带有可变参数的方法
    public static void show(int count,int... num){
            //在方法中怎么获取实际传递进来的参数,可变参数本质就是一个数组
            system.out.println(num.length);
            for (int i = 0; i < num.length; i++) {
                system.out.println(num[i]);
            }
        }
    }


/*
 * 1.定义自定义规则的map集合
 * 
 * 2.产生一副牌(存储的是序号)
 * 
 * 3.洗牌(序号的集合)
 * 
 * 4.发牌(发的就是序号)
 * 
 * 5.要求三个玩家以及地主牌进行排序(sort方法)
 * 
 * 6.看牌(根据序号从自定义的map集合中取值)
 * 
 * 
 */
public class doudizhudemo {

    public static void main(string[] args) {
        // todo auto-generated method stub
        //1.定义规则的map集合
        map<integer, string> map = new linkedhashmap<integer, string>();
        //2.定义一个牌集合
        arraylist<integer> cards = new  arraylist<integer>();
        //添加牌 一张牌 数值+花色
        string[] nums = {"3","4","5","6","7","8","9","10","j","q","k","a","2"};
        string[] colors = {"♠","♥","♣","♦"};
        //拼接一个张牌 
        int id = 54;//1234
        for (string num : nums) {
            for (string color : colors) {
                string card = color+num;
                map.put(id, card);
                cards.add(id);
                id--;
                //system.out.println(card);
            }
        }
        //添加大王小王
        map.put(2, "小s");
        cards.add(2);
        map.put(1, "大s");
        cards.add(1);
        //3.洗牌
        collections.shuffle(cards);
        //4.发牌
        //定义三个集合
        arraylist<integer> p1 = new arraylist<integer>();
        arraylist<integer> p2 = new arraylist<integer>();
        arraylist<integer> p3 = new arraylist<integer>();
        //定义地主牌的集合
        arraylist<integer> dp = new arraylist<integer>();
        //遍历54张牌
        for (int i = 0; i < cards.size(); i++) {
            integer card = cards.get(i);
            //如果是最后三张,不发,保存到地主牌的集合中
            //i 53 52 51
            if(i>=51){
                //不发
                dp.add(card);
                
            }else{
                //0 p1 1 p2  2 p3  3 p1
                if(i%3==0){
                    //给p1发牌
                    p1.add(card);
                }else if(i%3==1){
                    p2.add(card);
                }else{
                    p3.add(card);
                }
            }
        }
        //5.排序
        collections.sort(p1);
        collections.sort(p2);
        collections.sort(p3);
        collections.sort(dp);
        //看牌
        lookcards(p1,map);
        lookcards(p2,map);
        lookcards(p3,map);
        lookcards(dp,map);
    }
    /*
     * 看牌
     */
    public static void lookcards(arraylist<integer> cards,map<integer, string> map){
        //根据每一张的编号从 map中取出打印
        for (integer id : cards) {
            string card = map.get(id);
            system.out.print(card+" ");
        }
        system.out.println();
    }
    

}

/*

map 里面有个方法:  boolean containskey : 判断map集合中是否包含指定值 

hashset:底层是哈希算法实现.
linkedhashset:底层是链表实现,但是也是可以保证元素唯一,和hashset原理一样.

treeset:底层是二叉树算法实现.
一般在开发的时候不需要对存储的元素排序,所有在开发的时候大多用hashset,hashset的效率比较高
treeset在面试的时候比较多,问你有几种排序方式,和几种排序方式的区别?

 2.    treeset总结
1). treeset的特点
(1). 可以对元素进行排序
       有两种排序方式。
(2). treeset保证元素的唯一性依据
       在实现的comparable的compareto或者comparator的compare方法中,如果这两个方法的返回值为0,那么treeset就认为这两个元素一样。按照set的唯一性规则,在一次重复的元素不能被添加到treeset这个集合中。
2). treeset的两种排序方式
(1). 让元素本身具有比较性
       元素本身要实现comparable接口并实现里面的compareto方法以保证元素本身具有比较性
(2). 让容器自身具有比较性
       当元素本身不具有比较性或者具备的比较性不是所需要的,就在treeset建立实例的时候,传入comparator接口的实现子类的实例。这个comparator子类必须实现compare方法。
 
(3). 元素的可存储性
[1]. 自定义的类,如果重写了hashcode和equals两个方法,可以存入hashset容器
[2]. 自定义的类,如果实现了comparable的compareto()方法,可以存入treeset容器。
【总结】如果自定义的类既重写了hashcode和equals,又实现了compareto,那么这个类的元素既可以存入hashset容器,也可以存入treeset容器。

map
    hashmap :底层是哈希算法,针对键
        linkedhashmap:底层是链表,针对键.
    
    treemap:底层是二叉树算法,针对键.(开发中hashmap比较多)
collection
     list(存取有序,有索引,可以重复)
        arraylist:底层是数组实现的,线程不安全,查找和修改快,增和删比较慢.
        linkedlist:底层是链表实现的,线程不安全,增和删比较快,查找和修改比较慢
        vector : 底层是数组实现的,线程安全的,无论增删改查都慢.
    
    如果查找和修改多,用arraylist.
    如果增和删多,用linkedlist.
    如果都多,用arraylist
    set(存取无序,无索引,不可以重复)
        hashset
            linkedhashset
        treeset

        
//获取字符串中每个字符的个数
public class demo11 {
    public static void main(string[] args) {
        string sbc = "kalsdjfoisoigjsljlfklkadaooaijfa";
        //将字符串变成一个字符数组
        char[] chs = sbc.tochararray();
        //遍历这个字符数组,一个一个的进行比较,但是要计算数量,那么用那个集合好点?map,为什么map,可以显示效果,'a',1  'b'2
        map<character, integer> map = new hashmap<>();
        
        //遍历字符数组
        for(char c : chs) {
            //判断map里面有没有键是c的?
            boolean flag = map.containskey(c);
            //代表map里面有键是c的,那么数量就需要++
            if(flag) {
                //在原先的数量上加上1,根据键找值
                map.put(c, map.get(c)+1);
            }else {
                //就是map集合里面没用这个字符,如果说是没有的话,那么说明是第一次.
                map.put(c, 1);
            }
            
        }
        system.out.println(map);
        
    }
}