开篇说明
本场 Chat 主要以 Java 语言结合 JDK 1.8 相关源码来说明数据结构和一些常用的算法,不断提高自身内功修为。从线性表、队列和栈一直到树结构结合源码实例来进行说明,在上一篇 Chat《Java 编程(30 条建议)》中讲了在编程过程中要注意的一些部分,这一节准备以数据结构结合一些实例说明再到算法概念的基础讲解和一些举例说明。通过这些基础东西的研究,后面会针对再写一些关于 Java 开发框架相关的讲解,到后面我们会发现往往最难的是逻辑而不是工具框架的使用技能。什么是数据结构:数据之间相互存在的一种或多种特定的关系的元素的集合。在 Java 开发数据结构可是说是算法的基础,也就是说只有在熟悉数据结构的基础上,进行相应的算法设计才能写出好的算法。二、数据结构通常数据结构分为逻辑结构、物理结构。逻辑结构是指数据对象中数据元素之间的相互关系,而物理结构是指数据的存储结构。逻辑结构主要是集合结构、线性结构、树形结构、图形结构。物理存储结构主要是链式存储和线性存储。Java 线性表结构在 Java 语言中大家都知道,线性表 ArrayList 和 LinkedList 两种。对于这两种数据结构的优缺点肯定是前者查询速度快、后者插入和删除速度快,这里不进行赘述。下面使用一张图片来展示线性表的线性存储结构:在这里插入图片描述(图片来源:线性存储结构)以上图为例,作为线性存储时,数据的每一个下标位置都是独立的,比如我们在进行删除操作时删除线性表中的一个数据 a1,那么紧跟着 a2 就会变成 a1,a3 就会变成 a2,以此类推,这样删除一个数据那么每个数据的位置都会发生改变。同样的在进行插入操作时也会产生这种影响,因此,像 Java 中的 ArrayList 就适合运用在查询相关的操作。接下来我们再看线性表的链式存储结构。链式存储结构:在这里插入图片描述(图片来源:链式存储结构)相比线性存储结构,链式结构可以通过附加变量的形式指向前一个或者后一个数据对象类似于 C 语言中指针的形式,这样以来我们在删除数据或者是添加数据的时候就可以只改变前后相邻的两个变量。所以这就是为什么 Java 中的 LikedList 适用于做添加和删除操作。Java 实现首先来看 ArayList 和 LinkedList 在 Java 中的实现过程以及查看它的内部成员方法都是如何实现的,通过一部分的代码的说明来深入理解他们的数据结构。1. ArrayList 对象类内部方法实现过程分析ArrayList 继承并且实现的接口有哪些?我们通过查看它的源码结构,可以看到如下面代码块中的内容:public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable{}ArrayList 构造方法:/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative / public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }构造方法中定义集合长度,在默认情况下自动扩展长度。有时候为了节约内存的消耗,定义 List 时可以给它一个长度,但前提是长度必须是我们够用的。get 和 set 方法:/* * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} / public E get(int index) { rangeCheck(index); return elementData(index); } /* * Replaces the element at the specified position in this list with * the specified element. * * @param index index of the element to replace * @param element element to be stored at the specified position * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} / public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }通过上述两个方法可以看到在设置或者获取对象时都是通过操作一维数组的下标索引进行的。在底层通过将数据对象存储到数组中进行操作,并没有像是链表存储结构的那种前后指向。包括下面的 add 方法也是一样的道理。add 方法: /* * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return true (as specified by {@link Collection#add}) / public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }remove 方法:public E remove(int index) { rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); this.modCount = parent.modCount; this.size–; return result; }上述是 remove 方法都是一些比较常用的方法,ArrayList 的增加、删除都是需要进行每个元素进行下标移动的,然后改变数组的总长度实现的。还有关于遍历的方法我们可以查看迭代器实现,在实际的开发应用中如下操作,我们会使用迭代器进行集合的遍历等等操作:List lists = new ArrayList(); Iterator strs = lists.iterator(); while(strs.hasNext()){ System.out.println(strs.next()); }通过将集合对象交给迭代器来完成遍历的操作,当然也可以查看迭代器对象的接口方法和实现过程。2. LinkedList 内部成员方法实现及过程分析LinkedList 构造方法:/* * Constructs an empty list. / public LinkedList() { } /* * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection’s * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null / public LinkedList(Collection<? extends E> c) { this(); addAll©; }可以看到 LinkedList 的构造方法不像 ArrayList 那样可以设置数组长度等操作,只有一个空参构造和有参集合并没有关于长度的设置,接着来看它里面具体的 CRUD 方法来分析。set 和 get 方法:/* * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { checkElementIndex(index); return node(index).item; }
java
最新推荐文章于 2024-04-04 15:20:28 发布