【java筑基】面试必会的map集合

简介: 【java筑基】面试必会的map集合

90b32c83dc7c484dbbb772658ff5167b.gif

实际上,map集合和set集合非常类似,如果把Map集合中所有的Key单独来看,就组成了一个Set集合。事实上,Map中提供了keySet()方法,用于返回由key组成的Set集合。而从源码来看,Java是先实现了Map集合,然后将一个所有value都为null值得Map封装成了Set集合。如果把Map集合中的value当独来看,则与List集合很类似,元素可以重复,可以根据索引(key)来查找。

    public class MapTest {
      public static void main(String[] args) {
        Map map = new HashMap();
        map.put("人生得意须尽欢", 105);
        map.put("莫使金樽空对月", 62);
        map.put("古来圣贤皆寂寞", 88);
        // value值可以重复
        map.put("唯有饮者留其名", 62);
        // 放入重复得key值,会覆盖原有得value值,返回被覆盖value值,62
        System.out.println(map.put("莫使金樽空对月", 10));
        for (Object key : map.keySet()) {
          // 迭代输出key值及对应value值
          System.out.println(key + "-->" + map.get(key));
        }
      }
    }

HashMap允许value重复,但是key值不可以重复,如果添加的key-value对中key重复了,新的value会覆盖原来的value,put方法返回原来被覆盖的value。

Hashtable也是Map的实现类,线程安全,key、value不允许存放null,而HashMap则允许。Hashtable类也过于古老,最好不要使用,而是使用Collections工具类将HashMap类变为线程安全的类。

    public class NullHashMap {
      public static void main(String[] args) {
        HashMap hm = new HashMap();
        hm.put(null, null);
        hm.put(null, null);
        hm.put("a", null);
        //{null=null, a=null}
        System.out.println(hm);
      }
    }

HashMap与Hashtable通过equals()和hashCode()方法比较key值是否相等,通过equals()方法比较value是否相等。

不要使用可变对象作为HashMap、Hashtable的key,否则当key被改变,会造成程序无法访问map集合中key被改变的元素。

    class A {
      int count;
      public A(int count) {
        this.count = count;
      }
      public boolean equals(Object obj) {
        if (obj == this) {
          return true;
        }
        if (obj != null && obj.getClass() == A.class) {
          A a = (A) obj;
          return this.count == a.count;
        }
        return false;
      }
    }
    public class HashMapErrorTest {
      public static void main(String[] args) {
        HashMap ht = new HashMap();
        ht.put(new A(111), "你若精彩,蝴蝶自来");
        ht.put(new A(12345), "漠漠水田飞白鹭,阴阴夏木啭黄鹂");
        Iterator it = ht.keySet().iterator();
        A first = (A) it.next();
        first.count = 1998;
        // {mapdemo.A@15db9742=你若精彩,蝴蝶自来, mapdemo.A@6d06d69c=漠漠水田飞白鹭,阴阴夏木啭黄鹂}
        System.out.println(ht);
        ht.remove(new A(1998));
        // {mapdemo.A@15db9742=你若精彩,蝴蝶自来, mapdemo.A@6d06d69c=漠漠水田飞白鹭,阴阴夏木啭黄鹂}
        System.out.println(ht);
        // null
        System.out.println(ht.get(new A(1998)));
        // null
        System.out.println(ht.get(new A(111)));
      }
    }

LinkeHashMap以双链表来维护集合中key-value对的次序,有利于迭代。

Properties类是Hashtable的子类,相当于一个key、value值都是String类型的Map,主要用于处理属性文件。

    public class PropertiesTest {
      public static void main(String[] args) throws FileNotFoundException,
          IOException {
        Properties props = new Properties();
        props.setProperty("username", "banjiu");
        props.setProperty("password", "123456");
        props.store(new FileOutputStream("a.ini"), "comment line");
        Properties props2 = new Properties();
        props2.setProperty("gender", "male");
        //将a.ini文件中的key-value追加到props2中
        //{password=123456, gender=male, username=banjiu}
        props2.load(new FileInputStream("a.ini"));
        System.out.println(props2);
      }
    }

Properties类可以把key-value存储至xml文件,也可以从xml文件中读取key-value对,与上示代码类似。

SortedMap的实现类TreeMap可以实现元素排序,其底层结构为红黑树。利用compareTo()方法来比较元素key大小,判断其是否相等。若使用自定义的类作为key值,则应该保证重写的equals()与compareTo()返回结果一致。

    class R implements Comparable {
      int count;
      public R(int count) {
        this.count = count;
      }
      public String toString() {
        return "R[count" + count + "]";
      }
      public boolean equals(Object obj) {
        if (this == obj)
          return true;
        if (obj != null && obj.getClass() == R.class) {
          R r = (R) obj;
          return r.count == this.count;
        }
        return false;
      }
      @Override
      public int compareTo(Object obj) {
        R r = (R) obj;
        return count > r.count ? 1 : count < r.count ? -1 : 0;
      }
    }
    public class TreeMapTest {
      public static void main(String[] args) {
        TreeMap tm = new TreeMap();
        tm.put(new R(3), "莫欺少年穷");
        tm.put(new R(-5), "天下何人不识君");
        tm.put(new R(9), "朋友一生一起走");
        // {R[count-5]=天下何人不识君, R[count3]=莫欺少年穷, R[count9]=朋友一生一起走}
        System.out.println(tm);
        System.out.println(tm.lastKey());
        // 比2大的最小key值
        System.out.println(tm.higherKey(new R(2)));
        //{R[count3]=莫欺少年穷}
        System.out.println(tm.subMap(new R(-1), new R(4)));
      }
    }

WeakHashMap类的key为弱引用,当垃圾回收了该key所对应的实际对象后,WeakHashMap会删除对应的key-value对。

    public class WeakHashMapTest {
      public static void main(String[] args) {
        WeakHashMap whm = new WeakHashMap();
        //key为匿名字符串对象
        whm.put(new String("语文"), new String("良好"));
        whm.put(new String("数学"), new String("优秀"));
        whm.put(new String("英语"), new String("中"));
        //key为字符串直接量,系统会自动保留其强引用
        whm.put("java", new String("中等"));
        // {java=中等, 数学=优秀, 英语=中, 语文=良好}
        System.out.println(whm);
        System.gc();
        System.runFinalization();
        //通常情况下,结果为{java=中等}
        System.out.println(whm);
      }
    }

IdentityHashMap在比较两个元素时需要key完全相等(key1==key2),而普通的HashMap仅仅需要equals()返回true且hashcode值相同。其它性质与HashMap基本类似。

```java

public class IdentityHashMapTest {

public static void main(String[] args) {

IdentityHashMap ihm = new IdentityHashMap();

// 下两行添加两个元素

ihm.put(new String(“卡布奇诺”), 99);

ihm.put(new String(“卡布奇诺”), 90);

// 下两行添加一个元素

ihm.put(“烧仙草”, 18);

ihm.put(“烧仙草”, 17);

//{卡布奇诺=99, 烧仙草=17, 卡布奇诺=90}

System.out.println(ihm);

}

}

EnumMap专门应用于枚举类,内部通过数组来实现,这种实现形式紧凑、高效;EnumMap按照自然排序(枚举值在枚举类中定义顺序)对元素进行排序;不允许key为null值。
​```java
 enum Season {
     SPRING, SUMMER, FALL, WINTER
 }
 public class EnumMapTest {
     public static void main(String[] args) {
         EnumMap ehm = new EnumMap(Season.class);
         ehm.put(Season.SUMMER, "夏日炎炎");
         ehm.put(Season.SPRING, "春暖花开");
         //{SPRING=春暖花开, SUMMER=夏日炎炎}
         System.out.println(ehm);
     }
 }
​```
HashMap是最常用的Map集合,能够提供快速的查询,Hashtable线程安全,带来性能损耗,同时过于古老,推荐使用Collections将HashMap变成线程安全进行替代。LinkedHashMap可以维护元素的插入顺序。TreeMap对集合元素进行了排序,可以通过toArray()生成key的数组,随后用binarySearch()对元素进行快速查找。EnumMap应用于枚举类,效率最高。
这篇文章就介绍到这里了,学习集合推荐多刷题,才能够真正学会应用,个人比较推荐使用这个网站:大厂真题:[大厂面试真题大全](https://www.nowcoder.com/exam/oj?page=1&tab=%E7%AE%97%E6%B3%95%E7%AF%87&topicId=295&fromPut=pc_csdncpt_banjiu_sf)


相关文章
|
12天前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
174 100
|
12天前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
174 101
|
25天前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
16天前
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
|
2月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
150 23
|
2月前
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
2月前
|
存储 NoSQL Java
Java Stream API:集合操作与并行处理
Stream API 是 Java 8 提供的集合处理工具,通过声明式编程简化数据操作。它支持链式调用、延迟执行和并行处理,能够高效实现过滤、转换、聚合等操作,提升代码可读性和性能。
|
4月前
|
安全 Java 数据库连接
让我们讲解一下 Map 集合遍历的方式
我是小假 期待与你的下一次相遇 ~
132 43
使用 entrySet 遍历 Map 类集合 KV
使用 entrySet 遍历 Map 类集合 KV
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用