ArrayList
ArrayListArrayList是线程不安全的 ArrayList和LinkedList对比? ArrayList底层是数组,查找快 LinkedList底层是链表,插入快 特性实现了三个标记接口:RandomAccess, Cloneable, java.io.Serializable,它们内部都没有方法和属性 123public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable 1、RandomAccess支持随机访问(基于下标),为了能够更好地判断集合是ArrayList还是LinkedList,从而能够更好选择更优的遍历方式,提高性能! RandmoAccess是java中用来被List实现,为List提供快速访问功能的。我们即可以通过元素的序号(下标)快速获取元素对象;这就是快速随机访问。 实现了RandomAccess的标记接口,支持基于下标的...
编译调试openjdk8
编译openjdk8编译环境 操作系统:Ubuntu16 boot jdk:jdk7(我用的是openjdk7) 编译的jdk:openjdk8 看源码工具:Clion 下载地址: ubuntuopenjdk1.7openjdk1.8openjdk1.8源代码 以下编译openjdk的步骤只是其中之一。openjdk 解压后目录下有一个README-builds.html文件,该文件是官方提供的构建步骤,每个环境都有,请大家参考。 构建编译环境 因为OpenJDK的各个组成部分有的是使用C++编译,有的是使用Java自身实现的,比如调试工具:jps、jstat等,还有一些核心jar包,如rt.jar、tools.jar等。所以编译这些Java代码需要一个可用的JDK,官方称这个JDK为“Bootstrap JDK”,所以boot jdk需要比你编译的jdk版本低,因此需要安装jdk1.7。 1.安装启动jdk1.7 123456789101112131415161718192021222324252627# 下载的jdk1.7文件:openjdk-7u75-b13-linux...
JVM之类加载的过程
类加载的过程类的生命周期是由7个阶段组成,但是类的加载说的是前5个阶段 加载1、通过类的全限定名获取存储该类的class文件(没有指明必须从哪获取) 2、解析成运行时数据,即instanceKlass实例,存放在方法区 3、在堆区生成该类的Class对象,即instanceMirrorKlass实例 就是说你可以改写openjdk源码,你写的程序能达到这三个效果即可 JVM 是懒加载模式 lazy loading 何时加载? 主动使用时: 1、new、getstatic、putstatic、invokestatic 2、反射 3、初始化一个类的子类会去加载其父类 4、启动类(main函数所在类) 5、当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果是REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化 预加载:包装类、String、Thread 从哪加载? 因为没有指明必须从哪获取class文...
JVM之Klass模型
Klass模型补充: OOP-Klass模型 OOP 指的是 Ordinary Object Pointer (普通对象指针),它用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象。而 Klass 则包含元数据和方法信息,用来描述Java类。 klass是类 oop klass是类的内存地址(指针) Klass :包含元数据和方法信息,用来描述Java类。 class 和 klass区别: class:Java类,Java代码 klass:Java类在JVM的存在形式,c++代码 在JDK8中,Java的每个类,在JVM中,都有一个对应的Klass类实例与之对应,存储类的元信息如:常量池、属性信息、方法信息…… klass模型类的继承结构: 从继承关系上也能看出来,类的元信息是存储在原空间的。 普通的Java类在JVM中对应的是instanceKlass类的实例,再来说下它的三个字类 InstanceMirrorKlass:用于表示java.lang.Class,Java代码中获取到的Class对象,实际上就是这个C++类的实例,存储在堆区,学名镜像类 Inst...
Java8特性之Optional类使用
前言这周写代码遇到了一个很大的bug,怪自己学艺不精,无法认清of方法和ofNullable方法的使用,用错了这两个方法。出现了空指针异常。在这里必须记录一下该两个方法的区别。 简介Optional类为了解决NullPointerException(NPE)问题,减少代码中的判空,实现函数式编程,给工程师们提供函数式的API。 我们平时在编码的时候需要不断的判断对象是否为空来做大量的处理,如: 123456789101112public void errorNullStyle(User user){ if(user != null){ Address address = user.getAddress(); if(address != null){ City city = address.getCity(); if(city != null && "".equals(city)){ // do so...
栈和队列
栈栈定义栈(stack )又称堆栈,它是运算受限的线性表。其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行插入、查找、删除等操作。 表中进行插入、删除操作的一端称为栈顶(top) ,栈顶保存的元素称为栈顶元素。相对的,表的另一端称为栈底(bottom) 当栈中没有数据元素时称为空栈;向一个栈插入元素又称为 进栈或 入栈;从一个栈中删除元素又称为 出栈或 退栈。由于栈的插入和删除操作仅在栈顶进行,后进栈的元素必定先出栈,所以又把堆栈称为 后进先出表(Last In First Out,简称LIFO) 12345678910111213141516171819栈接口,定义了栈的主要操作记住针对栈的专业词汇:push、pop、peekpublic interface Stack { // 返回堆栈的大小 public int getSize(); // 判断堆栈是否为空 public boolean isEmpty(); // 数据元素 e 入栈 public void push(Object e); // 栈顶元素出栈 public Object...
线性表之双向链表的实现
前言主要是模拟Java中的LinkList的实现。 LinkedList概述LinkedList是一种双向链表。 根据双向链表的特点,会有头节点和尾节点,并且节点之间是通过前驱指针和后继指针来维护关系的,而不是像数组那样通过位置下标来维护节点间关系的。所以既可以从头到尾遍历,又可以从尾到头遍历。 双向链表是包含两个指针的,pre指向前一个节点,next指向后一个节点,但是第一个节点head的pre指向null,最后一个节点的tail的next指向null。 LinkedList是一个继承于AbstractSequentialList,并实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性(addFirst(),removeLast()…),它可以被当作堆栈、队列或双端队列进行操作。 LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。 12345public class LinkedList<E&g...
线性表之其它链表
前言介绍双向链表和循环链表 简介双向链表单链表的一个优点是结构简单,但是它也有一个缺点,即在单链表中只能通过一个结点的引用访问其后续结点,而无法直接访问其前驱结点,要在单链表中找到某个结点的前驱结点,必须从链表的首结点出发依次向后寻找,但是需要Ο(n)时间。为此我们可以扩展单链表的结点结构,使得通过一个结点的引用,不但能够访问其后续结点,也可以方便的访问其前驱结点。扩展单链表结点结构的方法是,在单链表结点结构中新增加一个域,该域用于指向结点的直接前驱结点。扩展后的结点结构是构成双向链表的结点结构,如图所示: 双向链表是通过上述定义的结点使用 pre 以及 next 域依次串联在一起而形成的。一个双向链表的结构如图所示: 在双向链表中同样需要完成数据元素的查找、插入、删除等操作。在双向链表中进行查找与在单链表中类似,只不过在双向链表中查找操作可以从链表的首结点开始,也可以从尾结点开始,但是需要的时间和在单链表中一样。 在使用双向链表实现链接表时,为使编程更加简洁,我们使用带两个哑元结点的双向链表来实现链接表。其中一个是头结点,另一个是尾结点,它们都不存放数据元素,头结点的p...
线性表之单链表的实现
前言今天主要是来模拟单链表的基本功能。 简介链表是一系列的存储数据元素的单元,通过指针串接起来形成的,因此每个单元至少有两个域,一个域用于数据元素的存储,另一个域是指向其他单元的指针。这里具有一个数据域和多个指针域的存储单元通常称为 结点(node) 一种最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。因为只有一个指针结点,称为单链表。 特点链表的第一个结点和最后一个结点,分别称为链表的 首结点和 尾结点。尾结点的特征是其 next 引用为空(null)。链表中每个结点的 next 引用都相当于一个指针,指向另一个结点,借助这些 next 引用,我们可以从链表的首结点移动到尾结点。在单链表中通常使用 head 引用来指向链表的首结点,由 head 引用可以完成对整个链表中所有节点的访问。 在单链表结构中还需要注意的一点是,由于每个结点的数据域都是一个 Object 类的对象,因此,每个数据元素并非真正如图中那样,而是在结点中的数据域通过一个 Object类的对象引用来指向数据元素的。与数组类似...
线性表之顺序表的实现
前言今天主要是来模拟Java中ArrayList的基本功能。 List接口首先定义List接口 /** * 线性表接口 * * @ClassName List * @Description 线性表接口 * @Author HuangCanCan * @Date 2019/8/11 15:30 * @Version 1.0 **/ public interface List { /** * 返回线性表的大小,即数据元素的个数。 */ public int size(); /** * 返回线性表中索引为 index的数据元素 */ public Object get(int index); /** * 如果线性表为空返回 true,否则返回 false。 */ public boolean isEmpty(); /** * 判断线性表是否包含数据元素 e */ public boolean contains(Object e); /** ...