数据结构-Java Map 和 Set-2

简介: 数据结构-Java Map 和 Set

数据结构-Java Map 和 Set-1

https://developer.aliyun.com/article/1517082


Map和Set搜索

概念

Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关

以前常见的搜索方式有:


1. 直接遍历,时间复杂度为O(N),元素如果比较多效率会非常慢

2. 二分查找,时间复杂度为 O( ),但搜索前必须要求序列是有序的

上述排序比较适合静态类型的查找,即一般不会对区间进行插入和删除操作了,而现实中的查找比如:


1. 根据姓名查询考试成绩

2. 通讯录,即根据姓名查询联系方式

3. 不重复集合,即需要先搜索关键字是否已经在集合中

可能在查找时进行一些插入和删除的操作,即动态查找,那上述两种方式就不太适合了,本节介绍的Map和Set是一种适合动态查找的集合容器。


存储方式

和python中的Set和Dict类是类似的,他们有直接全部存储key的模型,和存放key-value键值对的模型:

  1. key模型,例如:
  • 快速查找一个单词是否在英文词典中
  • 快速查找某个名字是否在通讯录中


  1. key-value模型,比如:
  • 统计某一篇英文短报中,单词的出现个数,key为单词,value为单词出现的个数,也可以称为权值
  • 统计后楼梦中,个人物名字出现的次数,其key-value模型为<名字:次数>


Map是以key-value键值对的形式来存储,而Set使用的是key存储方式。

key-value:

key:

注意Map可以看做是一种特殊的Set类型,Set中key不会出现重复元素,Map中的key也不会,但是Map中的每一个key都多了一个与之对应的value权重


Map & Set 的使用

Map

概要

在前言中我们介绍过:


其中Map是单独的一个接口,没有继承自Collection,而Set接口继承Collection


单独的接口不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap


Map<String, Integer> treeMap = new TreeMap<>();


Map中传入类,以key-value的形式。其中key是唯一的,key不能有重复的,而value可以有重复的。


如果new 一个 TreeMap,那么就会以搜索树的方式插入。


  • Map的put方法,向容器中存放key-value值
  • Map重写了println和print方法,可以直接打印
public static void main(String[] args) {
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("hello",3);
        treeMap.put("world",4);
        System.out.println(treeMap);
}

运行结果为:

相对应的根据传入的类,print或者println会进行重载,以适应不同的情况。


但是需要注意的是,对Map进行插入的时候key不能为null,否则会抛出空指针异常(NullPointerException):

可比较性

对于Map中传入的key类,一定是可以比较的。

假设有一个student类:

class student {
    int age;
    String name;
    public student(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

在key值中传入student类:

    public static void main(String[] args) {
        Map<student, Integer> treeMap = new TreeMap<>();
        treeMap.put(new student(18,"张三"),3);
        treeMap.put(new student(19,"李四"),4);
        System.out.println(treeMap);
    }


编译会抛出异常如下:

也就是说传入的student是无法比较的。


Map元素的访问

由于Map不是数组类型,无法通过treeMap[ i ]的形式访问,编译抛出异常:

978f28e41bb493f14311229ce5c94d35_93b7574c1e414fc7803aca6079fbff97.png


java: 需要数组, 但找到java.util.Map<java.lang.String,java.lang.Integer>


使用for-each方法 来进行访问:

Map<String,Integer> treeMap = new TreeMap<>();
  1. 访问所有key,使用Map中的keySet()方法,返回Map中所有键值对key-value的key的集合
for(String e: treeMap.keySet()) {
            System.out.println(e);
}

访问所有的value,使用Map中的values()方法,返回Map中所有键值对key-value 的value的集合


for(Integer e: treeMap.values()) {
            System.out.println(e);
}

注意:for-each迭代无法直接遍历Map这种字典类型数据:

Map的方法

方法

作用

V get(Object key)

返回 key 对应的value值,key不存在则返回null

V getOrDefault(Object key, V defaultValue)

返回 key 对应的 value,key不存在,返回默认值

V put(K key, V value)

设置 key 对应的 value

V remove(Object key)

删除 key 对应的映射关系

Set<K> keySet()

返回所有 key 的不重复集合

Set<Map.Entry<K, V>> entrySet()

返回所有的 key-value 映射关系

Collection<V> values()

返回所有 value 的可重复集合

boolean containsKey(Object key)

判断是否包含 key

boolean containsValue(Object value)

判断是否包含 value


Set

概要

Set继承与Collection接口,而Map是独立的,Set,相较于Map这种key-value的存放形式,Set只需要存放key一个关键字:key是唯一的


对于Set,我们也把他称为集合,集合是一种数学概念,集合由一个或多个确定的元素所构成的整体

它具备如下性质:

  1. 无序性,一个集合中,每个元素的地位都是相同的,元素之间是无序的。集合上可以定义序关系,定义了序关系后,元素之间就可以按照序关系排序。但就集合本身的特性而言,元素之间没有必然的序
  2. 互异性,一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。有时需要对同一元素出现多次的情形进行刻画,可以使用多重集,其中的元素允许出现多次。


Set中的key同Map键值对key-value中的key一样,是无法直接修改的,如果要修改可以直接删除原来的key然后再重新添加即可。


Set的实现类有TreeSet和HashSet,还有LinkedHashSet,LinkedHashSet,他两是在HashSet的基础上维护的一个双向链表,用来记录元素的插入次序,让其在结构上有序。

互异性

有如下代码:其中add(Object x);是向set中添加元素的意思。

    public static void main(String[] args) {
        Set<Integer> set1 = new TreeSet<>();
        set1.add(1);
        set1.add(2);
        set1.add(3);
        System.out.println(set1);
    }

我们在set集合中添加数字1,2,3。可以发现打印结果为:

如果往里面添加两个1呢?

    public static void main(String[] args) {
        Set<Integer> set1 = new TreeSet<>();
        set1.add(1);
        set1.add(1);
        System.out.println(set1);
    }

运行结果只有1。这就是其互异性

集合Set的一个最大的作用,就是根据它的互异性来去掉重复元素

Set元素的访问

同Map的key访问方法。使用for-each迭代器

Set的方法

方法

说明

boolean add(E e)

添加元素,但重复元素不会被添加成功

void clear()

清空集合

boolean contains(Object o)

判断 o 是否在集合中

Iterator<E> iterator()

返回迭代器

boolean remove(Object o)

删除集合中的 o

int size()

返回set中元素的个数

boolean isEmpty()

检测set是否为空,空返回true,否则返回false

Object[] toArray()

将set中的元素转换为数组返回

boolean containsAll(Collection<?> c)

集合c中的元素是否在set中全部存在,是返回true,否则返回false

boolean addAll(Collection<? extends

E> c)

将集合c中的元素添加到set中,可以达到去重的效果

目录
相关文章
|
3月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
194 3
|
4月前
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
436 0
|
5月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
164 1
|
5月前
|
存储 Java 编译器
Java 中 .length 的使用方法:深入理解 Java 数据结构中的长度获取机制
本文深入解析了 Java 中 `.length` 的使用方法及其在不同数据结构中的应用。对于数组,通过 `.length` 属性获取元素数量;字符串则使用 `.length()` 方法计算字符数;集合类如 `ArrayList` 采用 `.size()` 方法统计元素个数。此外,基本数据类型和包装类不支持长度属性。掌握这些区别,有助于开发者避免常见错误,提升代码质量。
466 1
|
8月前
|
存储 安全 Go
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
237 9
|
9月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
141 5
|
10月前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
1096 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
10月前
|
存储 算法 Java
Java Set深度解析:为何它能成为“无重复”的代名词?
Java的集合框架中,Set接口以其“无重复”特性著称。本文解析了Set的实现原理,包括HashSet和TreeSet的不同数据结构和算法,以及如何通过示例代码实现最佳实践。选择合适的Set实现类和正确实现自定义对象的hashCode()和equals()方法是关键。
153 4
|
10月前
|
Java
那些与Java Set擦肩而过的重复元素,都经历了什么?
在Java的世界里,Set如同一位浪漫而坚定的恋人,只对独一无二的元素情有独钟。重复元素虽屡遭拒绝,但通过反思和成长,最终变得独特,赢得了Set的认可。示例代码展示了这一过程,揭示了成长与独特性的浪漫故事。
69 4
|
10月前
|
Java 开发者
Java Set:当“重复”遇见它,秒变“独宠”!
在Java编程中,Set接口确保集合中的元素不重复,每个元素都是独一无二的“独宠”。本文介绍了Set的两种常见实现:HashSet和TreeSet。HashSet基于哈希表实现,提供高效的添加、删除和查找操作;TreeSet基于红黑树实现,不仅去重还能对元素进行排序。通过示例代码,展示了这两种集合的具体应用,帮助开发者更好地理解和使用Set。
108 4