当前位置:   article > 正文

Java集合整理(Arraylist、Vector、Linklist)_arraylsit和linklist和vector

arraylsit和linklist和vector

1、类集概述

类集设置的目的(常用类库的重点):
对象数组有那些问题?普通的对象数组的最大问题在于数组中的元素个数是固定的,不能动态的扩充大小,所以最早的时候可以通过链表实现一个动态对象数组。但是这样做毕竟太复杂了,所以在Java中为了方便用户操作各个数据结构,所以引入了类集的概念,有时候就可以把类集称为java对数据结构的实现
在整个类集中的,这个概念是从JDK12 (Java2) 之后才正式引入的,最早也提供了很多的操作类,但是并没有完整的提出类集的完整概念。
类集中最大的几个操作接口: Collection、 Map、Iterator, 这三个接口为以后要使用的最重点的接口。 所有的类集操作的接口或类都在javautil包中。

Java类集结构图:.

  • Collection:用来存储单值
  • Map:用来存储双值
  • Iterator:迭代器可以用最优的方式来存取数据

在这里插入图片描述

2、链表

数组的动态扩容很费内存。主要表现在数组存储中不利于删除数据,删除数据后数据不连续,操作前移费内存。但链表就解决了这个问题。
链表 [Linked List]:链表是由一组不必相连(不必相连:可以连续也可以不连续) 的内存结构(节点) ,按特定的顺序链接在一起的抽象数据类型

补充:
抽象数据类型(Abstract Data Type [ADT]):表示数学中抽象出来的一些操作的集合。
内存结构:内存中的结构,如: struct、特殊内存块…等等之类;

数组和链表的区别和优缺点:

数组是一种连续存储线性结构,元素类型相同,大小相等。
数组的优点: 存取速度快
数组的缺点:
事先必须知道数组的长度
插入删除元素很慢
空间通常是有限制的
需要大块连续的内存块
插入删除元素的效率很低

链表是离散存储线性结构 n 个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点。

链表优点:空间没有限制 插入删除元素很快
链表缺点:存取速度很慢

删除指针:后一个指针向前移!

2、链表共分几类?
链表常用的有 3 类: 单链表、双向链表、循环链表。
在这里插入图片描述
单链表:只知道下一数据的下标
双链表:既知道上一个数据的下标,也知道下一个数据的下标
循环链表:首尾相连
链表的核心操作集有 3 种:插入、删除、查找(遍历)

单链表

//链表节点
class Node{
   
	Object data;
	Node next;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

单链表 [Linked List]:由各个内存结构通过一个 Next 指针链接在一起组成,每一个内存结构都存在后继内存结构(链尾除外) ,内存结构由数据域和 Next 指针域组成。
单链表实现图示:
在这里插入图片描述
解析:
Data 数据 + Next 指针,组成一个单链表的内存结构 ;
第一个内存结构称为 链头,最后一个内存结构称为 链尾;
链尾的 Next 指针设置为 NULL [指向空];
单链表的遍历方向单一(只能从链头一直遍历到链尾)
单链表操作集:
在这里插入图片描述

3、二叉树

二叉树是树的一种,每个节点最多可具有两个子树,即结点的度最大为 2(结点度:结点拥有的子树数)。

//二叉树节点
class Node{
   
	Object data;
	Node left;
	Node right;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

先序遍历(根-左-右):1-2-4-8-9-5-10-3-6-7
中序遍历:(左-根-右):8-4-9-2-10-5-1-6-3-7
后序遍历(左-右-根):8-9-4-10-5-2-6-7-3-1

4、Collection接口(重点)

Collection 接口是在整个 Java 类集中保存单值的最大操作父接口, 里面每次操作的时候都只能保存一个对象的数据。
此接口定义在 java.util 包中。
No. 方法名称 类型 描述1 public boolean add(E e) 普通 向集合中插入一个元素2 public boolean addAll(Collection<? extends E> c) 普通 向集合中插入一组元素3 public void clear() 普通 清空集合中的元素4 public boolean contains(Object o) 普通 查找一个元素是否存在5 public boolean containsAll(Collection<?> c) 普通 查找一组元素是否存在6 public boolean isEmpty() 普通 判断集合是否为空7 public Iterator iterator() 普通 为 Iterator 接口实例化8 public boolean remove(Object o) 普通 从集合中删除一个对象9 boolean removeAll(Collection<?> c) 普通 从集合中删除一组对象10 boolean retainAll(Collection<?> c) 普通 判断是否没有指定的集合11 public int size() 普通 求出集合中元素的个数12 public Object[] toArray() 普通 以对象数组的形式返回集合中的全部内容13  T[] toArray(T[] a) 普通 指定操作的泛型类型, 并把内容返回14 public boolean equals(Object o) 普通 从 Object 类中覆写而来15 public int hashCode() 普通 从 Object 类中覆写而来
本接口中一共定义了 15 个方法, 那么此接口的全部子类或子接口就将全部继承以上接口中的方法。
但是, 在开发中不会直接使用 Collection 接口。 而使用其操作的子接口: List、 Set。
之所以有这样的明文规定, 也是在 JDK 1.2 之后才有的。 一开始在 EJB 中的最早模型中全部都是使用 Collection 操作的, 所以很早之前开发代码都是以 Collection 为准, 但是后来为了更加清楚的区分, 集合中是否允许有重复元素所以, SUN在其开源项目 —— PetShop(宠物商店) 中就开始推广 List (允许重复)和 Set (不允许重复)的使用。

5、List接口(重点)

在整个集合中 List 是 Collection 的子接口, 里面的所有内容都是允许重复的。
List 子接口的定义:

public interface List<E> extends Collection<E>
  • 1

此接口上依然使用了泛型技术。 此接口对于 Collection 接口来讲有如下的扩充方法:
No. 方法名称 类型 描述1 public void add(int index,E element) 普通 在指定位置处增加元素2 boolean addAll(int index,Collection<? extends E> c) 普通 在指定位置处增加一组元素3 public E get(int index) 普通 根据索引位置取出每一个元素4 public int indexOf(Object o) 普通 根据对象查找指定的位置, 找不到返回-15 public int lastIndexOf(Object o) 普通 从后面向前查找位置, 找不到返回-16 public ListIterator listIterator() 普通 返回 ListIterator 接口的实例7 public ListIterator listIterator(int index) 普通 返回从指定位置的 ListIterator 接口的实例8 public E remove(int index) 普通 删除指定位置的内容9 public E set(int index,E element) 普通 修改指定位置的内容10 List subList(int fromIndex,int toIndex) 普通 返回子集合
在 List 接口中有以上 10 个方法是对已有的 Collection 接口进行的扩充。
所以, 证明, List 接口拥有比 Collection 接口更多的操作方法。
了解了 List 接口之后, 那么该如何使用该接口呢? 需要找到此接口的实现类, 常用的实现类有如下几个:
· ArrayList(95%) 、 Vector(4%) 、 LinkedList(1%)

5.1、ArrayList(重点)

ArrayList 是 List 接口的子类, 此类的定义如下:

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
  • 1
  • 2

此类继承了 AbstractList 类。 AbstractList 是 List 接口的子类。 AbstractList 是个抽象类, 适配器设计模式。

范例: 增加及取得元素
package org.listdemo.arraylistdemo;
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo01 {
   
	public static void main(String[] args) {
   
		List<String> all = new ArrayList<String>(); // 实例化List对象, 并指定泛型类型
		all.add("hello "); // 增加内容, 此方法从Collection接口继承而来
		all.add(0, "LAMP ");// 增加内容, 此方法是List接口单独定义的
		all.add("world"); // 增加内容, 此方法从Collection接口继承而来
		System.out.println(all); // 打印all对象调用toString()方法
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

ArrayList的构造方法

构造器 描述
ArrayList() 构造一个初始容量为10的空列表。
ArrayList​(int initialCapacity) 构造具有指定初始容量的空列表。
ArrayList​(Collection<? extends E> c) 按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表。

当用ArrayList() 创建一个长度为10的数组,当存储到11个数据时,会扩容1.5倍,知道扩容到足够位置,如果存储大量的数据,便会导致大量的内存空间被浪费,因此初次创建时需要创建大量的数据时,因使用ArrayList​(int initialCapacity)的一参构造方法,指定存储的数量。
ArrayList通过无参构造器构造的集合在开始时长度是多少?
为0.,然后当存入数据后,会比较发现存不下,在将容量扩容到10

package com.java.arrayListDemo;
import java.util.ArrayList;
public class Demo1 {
   
    public static void main(String[] args) {
   
        ArrayList<Integer> arr = new ArrayList();
        arr.add(100);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

进入add方法的中:

    public boolean add(E e) {
   
        modCount++;
        add(e, elementData, size);//add(要往集合中添加的内容,存数据的数组,数组的长度)
        return true;//只要调用add方法,一定返回True,必定为true
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

再看下add算法

    private void add(E e, Object[] elementData, int s) {
   
        if (s == elementData.length)//目前存的数据跟数据长度一致,说明已经存满了 
            elementData = grow();//存满的话,调用扩容算法,扩容后将新的数组赋值给elementData 
        elementData[s] = e;//正常存
        size = s + 1;//存完size(数组长度)+1
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

再看下add算法下的grow()算法

    private Object[] grow() {
   
        return grow(<
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/322041
推荐阅读
相关标签
  

闽ICP备14008679号