在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,在第37条中建议 用EnumMap替换序数索引,为什么? EnumSet 在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段 36、用 EnumSet替代位字段 如果枚举类型的元素主要在 Set 中使用,传统上使用 int 枚举模式,通过不同的 2 的平方数为每个常量赋值: // Bit
写在前面 从一道Leetcode题目说起 首先,来看一下Leetcode里面的一道经典题目:146.LRU缓存机制,题目描述如下: 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说TreeSet里面有一个TreeMap(适配器模式)。 Java TreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator)。
为什么不推荐使用Stack Java已不推荐使用Stack,而是推荐使用更高效的ArrayDeque 为什么不推荐使用 性能低:是因为 Stack 继承自 Vector, 而 Vector 在每个方法中都加了锁。由于需要兼容老的项目,很难在原有的基础上进行优化,因此 Vector 就被淘汰掉了,使用 ArrayList 和 CopyOnWriteArrayList 来代替,如果在非线程安全的情
HashMap是Java中最常用的集合类框架,也是Java语言中非常典型的数据结构, 而HashSet和HashMap者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说HashSet里面有一个HashMap(适配器模式)。因此了解HashMap源码也就了解HashSet了 介绍 Key的存储方式是基于哈希表的 HashMap是 Map 接口 使用频率最高的实现类。 允
介绍 优先级队列的作用是能保证每次取出的元素都是队列中权值最小(或最大)的。这里元素大小的评判可以通过元素本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator)。 Java中PriorityQueue实现了Queue接口,不允许放入null元素;其通过 堆 实现,具体说是通过完全二叉树(complete binary tree)实现的小顶堆(任意一
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它既可以看作一个顺序容器,又可以看作一个队列(Queue),同时又可以看作一个栈(Stack)。这样看来,LinkedList简直就是个全能冠军。当你需要使用栈或者队列时,可以考虑使用LinkedList,一方面是因为Java官方已经声明不建议使用Stack类,更遗憾的是,Java里根本没有一个叫做Queue的类(它是个接口
Java 8的新特性之一就是流stream,配合同版本出现的 Lambda ,使得操作集合(Collection)提供了极大的便利。 案例引入 在JAVA中,涉及到对数组、Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行处理。 假设遇到了这么一个需求:从给定句子中返回单词长度大于5的单词列表,按长度倒序输出,最多返回3个。 在未接
为什么需要SPI机制 SPI和API的区别是什么 SPI是一种跟API相对应的反向设计思想:API由实现方确定标准规范和功能,调用方无权做任何干预; 而SPI是由调用方确定标准规范,也就是接口,然后调用方依赖此接口,第三方实现此接口,这样做就可以方便的进行扩展,类似于插件机制,这是SPI出现的需求背景。 SPI : “接口”位于“调用方”所在的“包”中 概念上更依赖调用方。 组织上位于调用
ArrayList介绍 ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现。除该类未实现同步外,其余跟Vector大致相同。每个ArrayList都有一个容量(capacity),表示底层数组的实际大小,容器内存储元素的个数不能多于当前容量。当向容器中添加元素时,如果容量不足,容器会增大底层数组的大小。 ArrayLi
介绍 每个类都有一个 Class 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。 类加载相当于 Class 对象的加载。类在第一次使用时才动态加载到 JVM 中,可以使用 Class.forName(".mysql.jdbc.Driver") 这种方式来控制类的加载,该方法会返回一个 Class 对
枚举的定义 在JDK1.5之前,我们要是想定义一些有关常量的内容,例如定义几个常量,表示从周一到周末,一般都是在一个类,或者一个接口中,写类似于如下代码: public class WeekDayConstant { public static final int MONDAY = 0; public static final int TUESDAY = 1; public
介绍 Throwable Throwable 是 Java 语言中所有错误与异常的超类。 Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。 Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。 Error(错误) Error 类及其子类:程序中
注解是否支持继承 不支持继承 不能使用关键字extends来继承某个@interface,但注解在编译后,编译器会自动继承java.lang.annotation.Annotation接口. 虽然反编译后发现注解继承了Annotation接口,但即使Java的接口可以实现多继承,但定义注解时依然无法使用extends关键字继承@interface。 区别于注解的继承,被注解的子类继承父类注解可以用
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。主要作用如下: 编写文档——通过注解中标识的元数据可以生成doc文档,这是最常见的,也是java 最早提供的注解。常用的有@param @return 等 代码分析——通过注解中标识元数据对代码进行分析。跟踪代码依赖性,实现替代配置文件功能。 编译检查——通过注解
类型擦除会造成多态的冲突,而JVM的解决方法就是泛型的桥接方法。 举例 现在有这样一个泛型类: class Pair<T> { private T value; public T getValue() { return value; } public void setValue(T value) {
概念 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体的值,那样这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。 优点 在编译的时候检查类型安全;使用泛型可以在编译
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. 什么时候会用到 当只在本地 JVM 里运行下 Java 实例,这个时候是不需要什么序列化和反序列化的,但当出现以下场景时,就需要序列化和反序列化了: 当需要将内存中的对象持久化到磁盘,数据库中时 当需要与浏览器进行交互时 当需要实现 RPC 时 但是当我们在与浏览器交互时,还有将
static能修饰的地方 静态变量 静态变量: 又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它;静态变量在内存中只存在一份。 实例变量: 每创建一个实例就会产生一个实例变量,它与该实例同生共死。 静态方法 静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法(abstract)。 只能
什么是值传递和引用传递? 值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身,两者指向同一片内存空间。所以对引用对象进行操作会同时改变原对象。 java中不存在引用传递,只有值传递。即不存在变量a指向变量b,变量b指向对象的这种情况。 clone() clone方法是Java中拷贝对象
为什么会哈希冲突 我们知道,在使用Map,Set这些集合时,都会重写hashcode方法,但Java中的hashCode方法会将对象映射到一个32位的整数范围(即从-2^31 到 2^31-1)。无论输入数据多么庞大,哈希函数生成的哈希值总是落在这个有限范围内。因此是会存在hash冲突的。 无论哈希函数设计得多么好,也无法避免所有冲突。一个好的哈希函数应尽可能地将输入数据均匀地分布到输出范围内,但
这是一个经典的问题,我们先从==开始看起 == "==" 是运算符 如果比较的对象是基本数据类型,则比较的是其存储的值是否相等; 如果比较的是引用数据类型,则比较的是所指向对象的地址值是否相等(是否是同一个对象)。 Person p1 = new Person("123"); Person p2 = new Person("123&qu
先说结论,是对象!可以继续往下看 数组是不是对象 什么是对象?对象是类的一个实例,有状态和行为 Java对象: 软件的对象也有行为和状态 软件对象的状态称之为属性 方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成 而java中的数组具有java中其他对象的一些基本特点。比如封装了一些数据,可以访问属性,也可以调用方法。 因此,数组是对象 证明 可以通过代码验证数组是对象的事实 C
先说下结论,可以自定义包名不为java.lang的String类,区别包名是可以正常使用的。 包名不为java.lang package .seven.jvm; public final class String { /** The value is used for character storage. */ private final char value[] = {}
String, StringBuffer 和 StringBuilder 可变性 String不可变 StringBuffer 和 StringBuilder 可变 线程安全 String 不可变,因此是线程安全的 StringBuilder不是线程安全的 StringBuffer 是线程安全的,内部使用 synchronized 进行同步 StringBu
能存储多少字符,通过以下步骤来看 首先String的length方法返回是int。所以理论上长度一定不会超过int的最大值。 编译器对字符串字面量长度的限制源自Java编译器(如javac)在处理常量池时的实现。编译器源码如下,限制了字符串长度大于等于65535就会编译不通过: // src/jdk.compiler/share/classes/com/sun/tools/javac/jv
Java中的String是不可变对象 在面向对象及函数编程语言中,不可变对象(英语:Immutable object)是一种对象,在被创造之后,它的状态就不可以被改变。至于状态可以被改变的对象,则被称为可变对象(英语:mutable object)。-- 来自百度百科 Java8 String源码 public final class String implements java.io.S
面试题引入 这里引申出一个经典问题,看下面代码 Integer a = 100; Integer b = 100; System.out.println(a == b);//true Integer c = 200; Integer d = 200; System.out.println(c == d);//false 为什么第一个输出的是true,第二个输出的是false? 源码分析 In
Copyright © 2005-2024 51CTO.COM 版权所有 京ICP证060544号