HashMap,TreeMap,LinkedHashMap的区别
Java 中的HashMap, TreeMap, 和 LinkedHashMap 都是实现 java.util.Map 接口的不同类,它们的主要区别在于数据存储结构、排序特性以及迭代顺序。以下是每个类的特点和使用场景: HashMap: 实现原理:基于哈希表(数组+链表或数组+链表+红黑树),通过 key 的 hashCode 值进行散列,并且当发生哈希冲突时采用链表或红黑树来解决冲突。 特点: 无序性:插入元素时没有特定的顺序,遍历结果不保证有序。 性能:查找、添加和删除操作的时间复杂度在平均情况下为 O(1)。 键值唯一:不允许有重复的键,但值可以重复。 线程安全性:非线程安全,在并发环境下需使用 Collections.synchronizedMap() 或 ConcurrentHashMap 来确保线程安全。 TreeMap: 实现原理:基于红黑树(自平衡二叉查找树)实现,自动对键进行排序。 特点: 有序性:根据键的自然顺序(对于实现了 Comparable...
HashMap保证线程安全的方法
在Java中,HashMap类本身并不是线程安全的。这意味着如果多个线程同时读写一个HashMap实例,可能会导致数据不一致或死锁等问题。为了保证线程安全,有以下几种方法可以实现: 使用 java.util.concurrent.ConcurrentHashMap ConcurrentHashMap 是专门为并发环境设计的线程安全的哈希表。它通过分段锁(Segment)机制来实现更高的并发性能,允许多个线程在同一时间对不同部分的数据进行操作。 使用 Collections.synchronizedMap() 包装 可以使用 Collections.synchronizedMap() 方法将一个普通的 HashMap 封装成线程安全的 Map 对象。这样得到的包装对象,在其上的所有操作都会被同步,从而保证线程安全。但请注意,即使进行了同步,迭代时也必须手动加锁,否则可能遇到并发修改异常。 使用 synchronized 关键字同步方法 在自定义类中,可以为 put, get, remove 等方法添加 synchronized...
HashMap其他注意事项
HashMap如果使用对象最为key,要注意什么?(难度:★★ 频率:★) 重写hashCode和equals。 对象比较为什么重写hashCode和equals?(难度:★★ 频率:★) 重写equals方法时需要重写hashCode方法,主要是针对Map、Set等集合类型的使用; a: Map、Set等集合类型存放的对象必须是唯一的; b: 集合类判断两个对象是否相等,是先判断HashCode是否相等,如果HashCode返回TRUE,还要再判断equals返回值是否ture,只有两者都返回ture,才认为该两个对象是相等的。
HashMap扩容的原理
Java中的HashMap在内部使用一个动态可调整容量的数组来存储元素,每个数组元素称为桶(bucket),桶中存放的是键值对对象(Node、TreeNode,在JDK1.8中是链表或红黑树)。当向HashMap中添加新的键值对时,会根据键的哈希码计算出对应的桶位置。随着元素数量的增加,如果继续添加元素导致负载因子(load factor)规定的阈值被超过,则会触发扩容操作。 扩容原理如下: 扩容时机: 当HashMap中的元素个数(size)超过当前容量(capacity)与加载因子(默认为0.75)的乘积时,即 size > capacity *...
Java中的static的用法
使用位置包括:修饰成员属性,修饰成员方法,修饰代码块,修饰内部类,静态导包。 修饰成员属性 给属性加了static关键字之后,对象就不再拥有该属性了,该属性会由类去管理,即多个对象只对应一个属性。 使用场景 一般用于定义一些常量。 1234567891011package com.example.a;class Test{ public static String NAME = "Tony";}public class Demo { public static void main(String[] args) { System.out.println(Test.NAME); }} 执行结果 1Tony 修饰成员方法 方法本来就是存放在类的定义当中的。static修饰成员方法的作用是可以使用"类名.方法名"的方式操作方法,避免了先要new出对象的繁琐和资源消耗。 示例: 12345678910111213package...
Java堆和栈
在Java编程语言中,堆(Heap)和栈(Stack)是两种不同的内存区域,它们有着不同的用途和管理方式。 堆(Heap) 1. 定义与功能: 堆是Java程序运行时的一个内存区域,它主要负责存储对象实例。每当使用new关键字创建一个对象时,该对象的引用以及它的实际数据(成员变量)都会在堆中分配空间。堆内存的特点是可以动态地分配和回收,这意味着你不需要在编译时就知道需要多少内存,而是在运行时根据需要申请和释放。 2. 管理方式: Java虚拟机(JVM)通过垃圾回收机制自动管理堆内存。当一个对象不再被任何引用指向时,垃圾回收器会识别并回收这部分内存,以防止内存泄漏。由于垃圾回收的过程较为复杂,因此访问堆内存的速度相对栈来说较慢。 3. 存储内容: 堆上存储的是所有由new创建的对象和数组,包括基本类型包装类的对象实例。 栈(Stack) 1. 定义与功能: 栈是一种线程相关的内存区域,每个Java线程都有自己的栈空间。栈主要用于存储方法调用时的局部变量、方法参数、返回地址(即程序计数器PC寄存器的内容),以及中间计算结果等临时数据。每一个方法调用都会创建一个新的栈帧(Stack...
Java的异常的类型
Java异常的层次结构 Throwable有两个直接的子类: Error、Exception。 Error JVM内部的严重问题,比如资源不足等,无法恢复。 处理方式: 程序员不用处理 Exception JVM通过处理还可回到正常执行流程,即:可恢复。 分RuntimeException和其他Exception,或者说分为非受检异常(unchecked exception)和受检异常(checked exception)也可以称为运行时异常和编译时异常 1使用建议:将checked exceptions用于可恢复的情况,将unchecked exception用于编程的错误。 运行时异常RuntimeException(unchecked exception) 处理或者不处理都可以(不需try…catch…或在方法声明时throws) 编译时异常,其他Exception(checked exception) Java编译器要求程序必须捕获(try…catch)或声明抛出(方法声明时throws)这种异常。
List集合去重方法
在Java中,对List集合去重有多种方法,以下是一些常见的实现方式: 使用HashSet(无序去重): 123List<String> listWithDuplicates = ...; // 假设这是包含重复元素的列表Set<String> set = new HashSet<>(listWithDuplicates);List<String> distinctList = new ArrayList<>(set); 这种方法利用了HashSet自动去除重复元素的特性。先将List转换为HashSet,然后创建一个新的ArrayList来存储不重复的元素。 使用LinkedHashSet(有序去重): 123List<String> listWithDuplicates = ...;LinkedHashSet<String> linkedSet = new LinkedHashSet<>(listWithDuplicates);List<String>...
List集合进行排序
在Java中,对List集合进行排序可以使用多种方法,以下是几种常见的排序方式: 使用Collections.sort(): 12345import java.util.Collections;import java.util.List;List<Integer> numbers = Arrays.asList(5, 3, 2, 8, 1);Collections.sort(numbers); // 对整型列表进行自然排序(升序) 如果你的List里存储的是自定义对象,你需要确保该类实现了Comparable接口,并重写了compareTo()方法,这样Collections.sort()才能根据对象的自然顺序进行排序。 使用Comparator: 12345678910111213141516class User { String name; int age; // 构造函数、getter和setter省略...}List<User> users = ...; //...
Set接口及主要实现类
...