1: java.util.Map接口常用的方法

  • Map和Collection没有继承关系
  • Map集合以key和value的方式存储数据:键值对
  • key和value都是引用数据类型
  • key和value都是存储对象的内存地址
  • key起到主导的地位,value是key的一个附属品

常用方法:

  • V put(K key, V value):向Map集合中添加键值对
  • *void clear():清空Map集合
  • boolean containsKey(Object key):判断是否包含某个key
  • boolean containsValue(Object value):判断是否包含某个value
  • V get(Object key):通过Key获取Value
  • boolean isEmpty()*:判断Map集合中元素个数是否为0
  • Set keySet():获取Map集合中所有的key
  • *V remove(Object key):通过key删除键值对
  • int size():获取Map集合中键值对的个数
  • Collection values():获取Map集合中所有的value,返回一个Collection
  • Set<Map.Entry<K,V>> entrySet()*:将Map集合转换成set集合
    ![在这里插入图片描述](
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapTest01 {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"zhangsan");//自动装箱
        map.put(2,"lisi");
        map.put(3,"lisi2");
        map.put(4,"lisi3");
        //通过key获取value
        String value = map.get(2);
        System.out.println(value);
        //获取所有的value
        Collection<String > values = map.values();
        for(String s:values){
            System.out.println(s);
        }
        //获取键值对的数量
        System.out.println(map.size());
        //通过key删除key-value
        map.remove(2);
        System.out.println("键值对的数量:"+map.size());
        //判断是否包含某个key
        System.out.println(map.containsKey(4));//底层调用equals,所以自定义类型需要重写equals方法
        //判断是否包含某个value
        System.out.println(map.containsValue("zhangsan"));//底层调用equals
        //清空map集合
        map.clear();
        //判断是否为空
        map.isEmpty();
    }
}

2. Map集合的遍历

方式一: 通过key获取value

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapTest02 {
    public static void main(String[] args) {
        //第一种方式,获取所有的key,通过遍历key来获取value
        Map<Integer,String> map = new HashMap();
        map.put(1,"zhangsan");
        map.put(2,"lisi");
        map.put(3,"wangwu");
        map.put(4,"zhaoliu");
        //遍历集合
        // 先获取所有的key,所有的key是一个set集合
        Set<Integer> keys = map.keySet();
        //迭代器
        Iterator<Integer> it = keys.iterator();
        while (it.hasNext()){
            Integer key = it.next();
            String value = map.get(key);
            System.out.println(key+"="+value);

        }
        //foreach
        for(Integer key:keys){
            System.out.println("通过foreach获取");
            System.out.println(map.get(key));
        }
    }
}

方式二 Set<Map.Entry<k,v>> entrySet()

原理:

java map 含有key java map是否存在key_java map 含有key

//Set集合中元素的类型是:Map.entry
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        //迭代器
        //遍历set集合,每次取出一个Node
        Iterator<Map.Entry<Integer,String>> it = set.iterator();
        while (it.hasNext()){
            Map.Entry<Integer,String> node = it.next();
            Integer key = node.getKey();
            String value = node.getValue();
            System.out.println(key+"="+value);

        }
        //foreach(适合大数据量的情况,效率比较高,因为获取key和value都是从node直接获取)
        for(Map.Entry<Integer, String> node:set){
            System.out.println(node.getKey()+">>>"+node.getValue());
        }

3. HashMap集合

- 是哈希表(散列表)的数据结构
哈希表是一个数组和单向链表的结合体

数组:在查询方面效率较高,随机增删方面效率很低
单向链表:在查方面效率很高,随机增删方面效率很低
哈希表将以上两种数据结构融合在一起,充分发挥它们各自的优点

java map 含有key java map是否存在key_数组_02

掌握Map中元素的存取原理:

java map 含有key java map是否存在key_System_03


重点:HashMap集合的key会先后调用两个方法,一个方法是hashCode(),一个方法是equals(),那么这两个方法都需要重写。

HashMap集合key的部分特点:

无序:因为不一定挂到哪个单链表上

不可重复:equals方法来保证HashMap集合的key不可重复,因为key重复了,value会被覆盖。

注意:

同一个单向链表上所有节点的hash相同,因为他们的数组下标是一样的。

但同一个链表上的k和k的equals方法肯定返回的都是false,都不相等。

哈希表使用不当是无法发挥性能:

  • 如果将所有的hashCode()方法返回为某个固定的值,那么会导致底层哈希表变成了纯单向链表。这种情况称为:散列分布不均匀。
  • 如果将所有的hashcode()方法的返回值都设定为不一样的值,那么会导致底层哈希表成了一位数组了,没有链表的概念了。也是散列分布不均匀。
  • 散列分布均匀需要在重写hashCode()时有一定的技巧。
重写hashCode()方法(重点)
  • HashMap集合的默认初始化容量是16,默认加载因子是0.75
    这个默认加载因子是当HashMap集合底层数组的容量达到75%的时候,数组开始扩容。
    HashMap集合初始化容量必须是2的倍数,为了达到散列均匀,为了提高HashMap集合的存取效率。

-向Map集合中存,以及从Map集合中取,都是先调用key的hashCode方法,然后再调用equals方法。
equals方法有可能调用,也可能不调用。k.hashCode()方法返回哈希值。哈希值经过哈希算法转换成数组下标。数组下标位置上如果是null,equals不需要执行。

  • 注意:如果一个类的equals方法重写了,那么hashCode()方法必须重写,并且equals方法返回如果是true(同一个单向链表上),hashCode()方法返回的值必须一样。
    直接用IDEA工具生成的equals和hashCode方法重写
    HashMap 集合key部分:允许为null,但是hashMap的key的null值只能有一个

4. Hashtable集合

不允许 key和value的值为null。
线程安全的,使用较少。
底层也是哈希表数据结构
初始化容量:11,默认加载因子:0.75,扩容之后是原容量的:*2+1

5. Properties

  • Properties是一个Map集合,继承自Hashtable集合。
  • key和value都是String类型
  • 被称为属性类对象
  • 是线程安全的
  • 需要掌握2个方法:存和取
import java.util.Properties;

public class PropertiesTest01 {
    public static void main(String[] args) {
        Properties pro = new Properties();
        // 存
        pro.setProperty("url","jdbc:mysql://localhost:3306");
        pro.setProperty("dirver","com.mysql.jdbc.Driver");
        pro.setProperty("username","root");
        pro.setProperty("password","123");
        // 取
        String url = pro.getProperty("url");
        System.out.println(url);

    }
}

6. TreeSet集合

  • 底层是一个TreeMap
  • TreeMap集合底层是一个二叉树
  • 放到TreeSet集合中的元素等同于放到TreeMap集合中的key部分
  • 无需不可重复,但是可以按照元素的大小顺序自动排序,可排序集合

java map 含有key java map是否存在key_java map 含有key_04


对于自定义的类型,TreeSet不可以排序。需要指定对象之间的比较规则。

自定义类型实现comparable接口:

放在TreeSet集合中的元素需要实现java.lang.Comparable接口
并且实现compareTo方法。equals可以不写。

import java.util.TreeSet;

public class TreeSetTest04 {
    public static void main(String[] args) {
        Customerz c1 = new Customerz(32);
        Customerz c2 = new Customerz(22);
        Customerz c3 = new Customerz(62);
        Customerz c4 = new Customerz(12);

        TreeSet<Customerz> customers = new TreeSet();
        customers.add(c1);
        customers.add(c2);
        customers.add(c3);
        customers.add(c4);

        for(Customerz c:customers){
            System.out.println(c);
        }

    }


}



class Customerz implements Comparable<Customerz>{
    int age;
    public Customerz(int age){
        this.age=age;
    }

// 需要再这个方法中编写比较的逻辑,或者说比较的规则,按照什么比较!
    // k.compareTo(t.key)
    //拿着参数k和集合中的每一个k进行比较,返回值可能是 >0 <0 =0
    //比较规则最终还是由程序员自己指定:例如按照年龄升序或者降序
    @Override
    public int compareTo(Customerz o) {//c1.compareTo(c2)
        //this是c1
        return this.age - o.age;
    }

    @Override
    public String toString() {
        return "Customerz{" +
                "age=" + age +
                '}';
    }
}