资讯专栏INFORMATION COLUMN

Java基础(笔记)

PrototypeZ / 2811人阅读

摘要:拆箱将包装类型转换为基本类型的过程。否则会抛出异常。默认采用单链表解决冲突,如果链表长度超过,将单链表转换为红黑树。内部使用红黑树实现,存储映射。红黑树减弱了对平衡的要求,降低了保持树平衡需要的开销,在实际应用中,统计性能超过平衡二叉树。

引言

在学习《Java编程的逻辑》一书时记录的一些笔记,扫清了一些Java基础的知识盲区,感谢作者马俊昌老师。

数据类型
序号 数据类型 大小(位) 包装类 默认值 数据范围
1 byte 8 Byte 0 -128 ~ 127
2 short 16 Short 0 -32768 ~ 32767
3 int 32 Integer 0 -2147483648 ~ 2147483647
4 long 64 Long 0L -9223372036854775808 ~ 9223372036854775807
5 boolean 8 Boolean false true/false
6 char 16 Character 0 ~ 65535
7 float 32 Float 0.0F 1.4E-45 ~ 3.4028235E38
8 double 64 Double 0.0D 4.9E-324 ~ 1.7976931348623157E308
装/拆箱

装箱:将基本类型转换为包装类的过程。

拆箱:将包装类型转换为基本类型的过程。

Java 5以后引入了自动装箱和拆箱技术:

Integer a = 100;
int b = a;

自动装箱/拆箱是Java编译器提供的能力,背后,它会替换为调用对应的valueOf/xxx-Value方法,比如,上面的代码会被Java编译器替换为:

Integer a = Integer.valueOf(100);
int b = a.intValue();
valueOf

一般建议使用valueOf方法。

new每次都会创建一个新对象,而除了FloatDouble外的其他包装类,都会缓存包装类对象,减少需要创建对象的次数,节省空间,提升性能。

缓存

IntegerCache表示Integer缓存,其中的cache变量是一个静态Integer数组,在静态初始化代码块中被初始化。

默认情况下,保存了-128~127256个整数对应的Integer对象。

valueOf代码中,如果数值位于被缓存的范围,即默认-128~127,则直接从Integer-Cache中获取已预先创建的Integer对象,只有不在缓存范围时,才通过new创建对象。

序号 数据类型 数据缓存
1 Boolean true, false
2 Byte -128 ~ 127
3 Short -128 ~ 127
4 Integer -128 ~ 127
5 Long -128 ~ 127
6 Character 0 ~ 127
7 Float 无缓存
8 Double 无缓存
Switch语句 支持的数据类型

Java 5之前,只支持byteshortintchar四种。

Java 5中,引入了枚举类型。因为枚举类的ordinal返回一个int值。

Java 7中,支持String类型,使用StringhashCode方法。

原因

switch的效率相对较高,编译后使用跳转表实现。

跳转表有序,可以二分查找,所以支持的数据类型都是整数,枚举和String也是转换为int值。

跳转表的存储空间是32位,容纳不下long,所以switch不支持long类型。

接口

接口中变量修饰符是public static final

接口中方法修饰符是public abstract

java 8允许在接口里定义默认方法default和静态方法static

java 9允许默认方法和静态方法可以是private

序列化 条件

一个类的对象要想序列化成功,必须满足两个条件:

该类必须实现java.io.Serializable接口。

该类的所有属性必须是可序列化的。如果不想序列化,则将该属性注明为transient

否则会抛出NotSerializableException异常。

注意

虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化ID是否一致。

序列化并不保存静态变量。

父类如果没有实现Serializable接口时,反序列化时,会调用父类无参的构造函数。

Externalizable

Externalizable接口继承自java.io.Serializable

public interface Externalizable extends java.io.Serializable {

    void writeExternal(ObjectOutput out) throws IOException;

    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

实现Externalizable接口后,序列化的细节由开发人员自己实现。

并且Externalizable的优先级比Serializable的优先级高。

异常

try/catch/finally语法中,catch不是必需的,也就是可以只有tryfinally,表示不捕获异常,异常自动向上传递,但finally中的代码在异常发生后也执行。

java 7开始支持:多个异常之间可以用|操作符:

try {
    // 可能抛出ExceptionA和ExceptionB
} catch (ExceptionA | ExceptionB e) {
    // 异常处理逻辑
}
try-with-resources

java 7提供了一种新的语法,称之为try-with-resources

这种语法针对实现了java.lang.AutoCloseable接口的对象,接口定义:

public interface AutoCloseable {
    void close() throws Exception;
}

语法形式如下:

try (AutoCloseable resource = new FileInputStream("yunzhi.txt")) {
    // 使用资源
}

资源resource的声明和初始化放在try语句内,不用再调用finally,在执行完try语句后,会自动调用资源的close方法。

String

String类内部用一个字符数组表示字符串,实例变量定义为:

private final char value[];
常量字符串
System.out.println("yunzhi.club".length());
System.out.println("yunzhi.club".contains("yunzhi"));
System.out.println("yunzhi.club".indexOf("yunzhi"));

实际上,这些常量就是String类型的对象,在内存中,它们被放在一个共享的地方,这个地方称为字符串常量池,它保存所有的常量字符串,每个常量只会保存一份,被所有使用者共享。

当通过常量的形式使用一个字符串的时候,使用的就是常量池中的那个对应的String类型的对象。

+/+=

Java中,String可以直接使用++=运算符,这是Java编译器提供的支持,背后,Java编译器一般会生成StringBuilder++=操作会转换为append

String hello = "hello";
hello += ", world";
System.out.println(hello);

背后,Java编译器一般会转换为:

StringBuilder hello = new StringBuilder("hello");
hello.append(", world");
System.out.println(hello.toString());

对于简单的情况,可以直接使用String++=,对于复杂的情况,尤其是有循环的时候,应该直接使用StringBuilder

为什么要定义为不可变类呢?

不可变使得程序更为简单安全,因为不用操心数据被意外改写的可能,可以安全地共享数据,尤其是在多线程的环境下。

Map和Set HashMap

效率高。

无序,因为hash值是无序的。

默认采用单链表解决冲突,如果链表长度超过8,将单链表转换为红黑树。

负荷系数
static final float DEFAULT_LOAD_FACTOR = 0.75f;
为什么容量是2的幂

申请内存时,减少内存碎片。

进行移位操作,效率高。

tab[i = (n - 1) & hash],使用n-1&运算,提高效率。

其他

扩容的条件:实际节点数大于等于容量的0.75,就是负荷系数。

因为不同版本的JDK计算的hash值可能是不同的。只存储了数组的容量、实际节点数量和各个节点的key value值。

HashSet

元素不重复。

添加、删除、判断元素是否存在都是O(1)的复杂度。

无序。

HashSet内部是调用HashMap来实现的,核心就是利用HashMap中的key不能相同进行去重,key就是Set中的值,value存了一个空对象。

TreeMap

TreeMap按键有序,为了实现有序,要求要么键实现Comparable接口,要么创建TreeMap时传递一个Comparator对象。

内部使用红黑树实现,存储映射。

红黑树

红黑树是一种平衡二叉树,但它不是高度平衡的,而是大致平衡的。确保任意一条从根到叶子节点的路径,没有任何一条的路径的长度会比其他路径长过两倍。

红黑树减弱了对平衡的要求,降低了保持树平衡需要的开销,在实际应用中,统计性能超过平衡二叉树。

TreeSet

TreeSet内部是基于TreeMap的,实现了有序。

LinkedHashMap

HashMap的子类,内部使用双向链表维护键值对的顺序,每个键值对既位于哈希表中,也位于这个双向链表中。

支持插入顺序维护或访问顺序维护。

插入顺序:先添加的在前面,后添加的在后面,修改操作不影响顺序。

访问顺序:对一个键值对进行get/put操作,该键值对会移动到链表末尾,最末尾的是最近访问的,最开始的是最久没有访问的。

LinkedHashSet

HashSet的子类,内部采用LinkedHashMap实现。

EnumMap

一个key是枚举类型的Map

内部使用了两个长度相同的数组,一个存键,一个存储对应的值,值为null表示没有该键值对。键都有一个对应的索引,根据索引可直接访问和操作其键的值,效率高。

EnumSet

EnumSet的实现和EnumMap没有任何关系!

采用位向量实现。0代表没有存这个枚举值,1代表存了这个枚举值,效率很高。

PriorityQueue

优先级队列,内部采用堆实现。和其他需要比较的操作一样,要么实现Comparable接口,要么创建时传递一个Comparator对象。

适用场景 TOP K问题

维护一个最小堆,堆的根节点是最小的,即第K大元素。

每次有新数据来,和根节点比,如果小,不操作,如果大,替换根节点,调整堆。调整的复杂度为O(logK)

求中值元素

维护一个最大堆和最小堆,假设当前中位数为M,最大堆维护<=M的元素,最小堆维护>=M的元素,但两堆中都不包含M

新数据来时,如果<=M,放到最大堆中,如果>=M,放到最小堆中。

数据加入之后,如果两堆元素相差>=2,将M加入到元素少的堆中,元素多的堆的根节点移除作为新的中值元素。

集合关系图

之前一直很怕这张图,但是随着积累,图中的类我们也逐渐地学会并掌握了。

Collections

Collections常用方法。

查找和替换
方法名 方法描述
binarySearch 二分查找
max 最大值
min 最小值
frequency 集合中元素出现次数
indexOfSubList lastIndexOfSubList 在原List中查找目标List的位置
disjoint 集合是否有交集
replaceAll List中元素替换
排序和调整顺序
方法名 方法描述
sort 排序
swap 元素交换
reverse 列表反转
shuffle 洗牌,随机打乱顺序
rotate 循环移位
适配器
方法名 方法描述
emptyList emptySet emptyMap emptyIterator 返回空的集合,使用时比返回null更合理,更安全
singleton singletonList singletonMap 将单一对象转化为标准容器接口对象
装饰器
方法名 方法描述
unmodifiableCollection unmodifiableList unmodifiableMap unmodifiableSet 让容器只读
synchronizedCollection synchronizedList synchronizedMap synchronizedSet 让容器线程安全,不是最优实现。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75954.html

相关文章

  • java&javaweb学习笔记(汇总)

    摘要:我的学习笔记汇总标签笔记分为两大部分和笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解基础语法,想进一步深入学习的人如果觉得不错,请给,这也是对我的鼓励,有什么意见欢迎留言反馈目录基础巩固笔记反射基础巩固笔记泛型基础巩 我的java&javaweb学习笔记(汇总) 标签: java [TOC] 笔记分为两大部分:javase和javaweb javase javawe...

    yagami 评论0 收藏0
  • Java入门请不要放弃,学习路线以及侧重点分析

    摘要:而面向搜索引擎,就是我们要及时的使用百度谷歌遇到问题无法解决,先别急着放弃,可以去网络寻找答案,你的坑大部分别人都已经走过了,大部分都可以找到合适的解决方案。 showImg(https://segmentfault.com/img/remote/1460000019236352?w=866&h=456); 前言: ●众多的语言,到底哪一门才是适合我的?●我们为什么要学习Java语言呢...

    mochixuan 评论0 收藏0
  • Java核心技术笔记 语言基础

    摘要:变量声明变量变量名规则字母开头,由字母或数字构成的序列,中的字母包括或者某种语言中代表字母的任何字符,数字包括或者某种语言中代表数字的任何字符。删除原始字符串头部和尾部空格。中断控制流程,使用在和循环中,用于提前中断循环。 《Java核心技术 卷Ⅰ》 第3章 Java 的基本程序设计结构 一些规则 类命名:CamelCase 驼峰命名法,以及必须是字母开头,后面跟字母和数字的任意组合...

    lindroid 评论0 收藏0
  • Java笔记基础数据类型

    摘要:的基础类型主要分为四大类,八小类。四大类分别为整数型,浮点数类型,布尔类型字符类型。是最常用的整数数据类型。布尔类型布尔类型有两个值和,用来判定的逻辑条件。基础类型的数据,直接存放在栈内存。基础类型的方法传参是通过值拷贝的方法。 Java的基础类型主要分为四大类,八小类。四大类分别为整数型,浮点数类型,布尔类型,字符类型。其中整数型有四中,容量从小到大分别为:byte,short,in...

    PingCAP 评论0 收藏0
  • 基础java学习笔记

    摘要:区分大小写语句以英文分号结尾一环境搭建安装建议和设置环境变量添加用户变量二使用创建工作空间,即选择适合的,如创建在目录下创建运行有方法的类,在试图中查看结果三第一个类方法必须这样写一个类里面可以有多个方法,但只能有一个方法,方法里的代码决定 1、java区分大小写2、语句以英文分号(;)结尾一、环境搭建1、安装JDK(建议java SE)和Eclipse for java2、设置环境变...

    xiangzhihong 评论0 收藏0
  • Java基础语法笔记

    摘要:注该笔记适合有基础或者有复习需求的小伙伴哦预习的话建议直接看视频俺舅是链接邀请码太过简单的知识点都被作者扔到回收站了所以这些知识点都是精华呦一快捷键与常见问题运行当前程序其它运行方法右键小虫子图像右边的图标运行错误运行 ...

    maochunguang 评论0 收藏0

发表评论

0条评论

PrototypeZ

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<