ArrayList和LinkedList区别

ArrayList

底层数据结构是数组

内存是连续的

有索引

查询速度快

增删速度慢

线程不安全的集合

默认无参构造时会创建一个长度为0的数组

第一次使用add,扩容为10

每次扩容是原来容量+原来容量/2

以下是手写实现方式,如有bug请指正

package cn.javasm.test;

import java.util.Arrays;
import java.util.Objects;

/**
 * @className: ArrayListDemo
 * @description:  模拟ArrayList
 * @author: gfs
 * @date: 2024/12/11 14:40
 * @version: 0.1
 * @since: jdk11
 */
public class ArrayListDemo {

    // 存储数据的数组
    private String[] data;
    // 元素的实际个数
    private int size;
    // 定义无参构造
    public ArrayListDemo(){
        // 默认的初始容量
        data = new String[10];
    }
    public int length(){
        return data.length;
    }

    @Override
    public String toString() {
        String str = "[";
        for (int i = 0; i < size - 1; i++) {
            str += data[i] + ", ";
        }
        if(size > 0)
        str += data[size - 1];
        str += "]";
        return str;
    }

    // 定义有参构造,根据用户传入的参数使用初始容量
    public ArrayListDemo(int len){
        // 判断参数是否合法
        if (len < 0) throw new IllegalArgumentException();
        
        data = new String[len];
    }

    /**
     * 判断是否需要扩容
     */
    private void Expansion() {
        // 判断是否需要扩容
        if (size >= data.length){
            if (data.length > 1){
                data = Arrays.copyOf(data,data.length + ((data.length) >> 1));
            }else {
                data = Arrays.copyOf(data,data.length + 1);
            }
        }
    }
    /**
     * 判断索引是否符合规范
     * @param index
     */
    private void judgeIndex(int index) {
        if(index > size || index < 0) throw new IndexOutOfBoundsException("您输入的索引不对");
    }
    /**
     * 添加元素方法
     * @param str 添加的元素
     */
    public void add(String str){
        //判断是否需要扩容
        Expansion();
        // 添加元素
        data[size++] = str;

    }


    /**
     * 根据索引插入到数组中
     * @param index
     * @param str
     */

    public void add(int index,String str){
//        判断索引是否符合规范
        judgeIndex(index);
//        判断是否要扩容
        Expansion();

//        如果是实际长度+1的索引,直接放入
        if(index == size){
            data[size++] = str;
            return;
        }

        for (int i = size; i >= index; i--) {
            data[i+1] = data[i];
        }
        data[index] = str;
        size++;
    }


    /**
     *
     * 清空数组
     */
    public void clear(){
        data = new String[10];
        size = 0;
    }

    /**
     * 查询数组中是否包含s
     * @param s
     * @return
     */
    public boolean contains(String s){
        return indexOf(s) != -1;
    }

    /**
     * 获取数组对应索引的值
     * @param index
     * @return
     */
    public String get(int index){
        //判断index  是否合法
        if(index >= size || index < 0) throw new IndexOutOfBoundsException("数组越界了");
        return data[index];
    }

    public void set(int index , String s){
        //判断index  是否合法
        judgeIndex(index);
        data[index] = s;
    }

    /**
     * 查询数组中第一次出现指定元素的索引,并返回对应索引
     * @param s
     * @return
     */
    public int indexOf(String s){
        for (int i = 0; i < size; i++) {
            if(Objects.equals(s,data[i])) return i;
        }
        return -1;
    }
    /**
     * 查询数组中最后一次出现指定元素的索引,并返回对应索引
     * @param s
     * @return
     */
    public int lastIndexOf(String s){
        for (int i = size; i > 0; i--) {
            if(data[i] == s) return i;
        }
        return -1;
    }

    /**
     * 查询数组是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 移除数组中第一次出现指定的元素
     * @param s
     * @return
     */

    public boolean remove(String s){
        int i = indexOf(s);
        if(i != -1) {
            for (int j = i; j < size - 1; j++) {
                data[j] = data[j + 1];
            }
            size--;
            data[size] = null;
            return true;
        }else {
            return false;
        }
    }
    /**
     * 移除数组中出现指定的元素
     * @param s
     * @return
     */

    public boolean removeAll(String s){
        boolean isFlag = false;
        while (remove(s)){
            isFlag = true;
        }
        return isFlag;


    }
    /**
     * 返回数组实际参数的个数
     * @return
     */
    public int size(){
        return size;
    }

    public ArrayListDemo subList(int fromIndex,int toIndex){
        if(fromIndex >= toIndex || fromIndex < 0 || toIndex > size) throw new IllegalArgumentException("索引不正确");
        ArrayListDemo sublist = new ArrayListDemo(toIndex - fromIndex);
        System.arraycopy(data,fromIndex,sublist,0,toIndex - fromIndex);
        sublist.size = toIndex - fromIndex;
        return sublist;
    }

    public void trimToSize(){
        data = Arrays.copyOf(data,size);

    }


    
    
}

LinkedList

底层数据结构是双向链表

内存是不连续的

无索引

查询速度慢

增删速度快

本质上一个对象是一个元素

以下是手写实现方式,如有bug请指正

package cn.javasm.demo;

import java.util.Objects;

/**
 * @className: LinkedList
 * @description:
 * @author: wj
 * @date: 2024/12/12 10:30
 * @version: 0.1
 * @since: jdk11
 */
public class LinkedListDemo {
//    实际元素个数
    private int size;
//    头节点
    private Node first;
//    尾节点
    private Node last;

    public void add(String str){
        Node node = new Node(str,null,null);

        if(size == 0){
//            第一个插入的话
            this.first = node;
        }else {
            node.prev = this.last;
            node.prev.next = node;
        }
        this.last = node;
        size++;
    }
    public Node get(int index){
        if(index >= size || index < 0) throw new IndexOutOfBoundsException("输入的索引不正确");
        Node node = first;
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node;
    }
    public int indexOf(String s){
        Node node = first;
        for (int i = 0; i < size; i++) {
            if(Objects.equals(s,node.data)) return i;
            node = node.next;
        }

        return -1;
    }

    public boolean contains(String s){
        return indexOf(s) != -1;

    }


    public void add(int index,String str){
        if(index > size || index < 0) throw new IndexOutOfBoundsException("输入的索引不正确");
        if(index == size) {
            add(str);
            return;
        }

        Node node = get(index);
        Node addNode = new Node(str,null,null);
        if(this.first == node){
            node.prev = addNode;
            addNode.next = node;
            this.first = addNode;
        }else {
            //      将加入的新地址更换
            addNode.next = node;
            addNode.prev = node.prev;
            node.prev.next = addNode;
            node.prev = addNode;
        }
        size++;
    }

    public LinkedListDemo remove(){
        if(size != 0){
            first = first.next;
            first.prev = null;
            size--;
        }
        return this;
    }

    public LinkedListDemo remove(int index){
        Node node = get(index);
        if(node == first){
            remove();
            return this;
        }else if(node == last){
            last.prev.next = null;
            last.prev = last;
            size--;
        }else {
            node.prev.next = node.next;
            node.next.prev = node.prev;
            node.prev = null;
            node.next = null;
            size--;
        }
        return this;
    }

    public boolean isEmpty(){
        return size == 0;
    }



    @Override
    public String toString() {
        StringBuilder str = new StringBuilder("[");
        Node node = first;
        for (int i = 0; i < size; i++) {
            if(i != size-1){
            str.append(node.data).append(", ");
            node = node.next;
            }else {
            str.append(node.data);
            }
        }
        str.append("]");

        return str.toString();
    }

    public void clear(){
        first = null;
        last = null;
        size = 0;
    }


    public int size(){
        return size;
    }
    public LinkedListDemo subList(int fromIndex,int toIndex){
        if(fromIndex > toIndex || fromIndex < 0 || toIndex > size) throw new IndexOutOfBoundsException();
        LinkedListDemo linkedListDemo = new LinkedListDemo();
        Node node = first;
        for (int i = 0; i < size; i++) {
            if(i >= fromIndex && i < toIndex) {
                linkedListDemo.add(node.data);
            }
            node = node.next;
        }
        return linkedListDemo;

    }
    public String set(int index, String str){
        Node node = get(index);
        node.data = str;
        return str;
    }





    private class Node {
//        数据
        private String data;
//        前一个节点
        private Node prev;
//        后一个节点
        private Node next;

        public Node(String data, Node prev, Node next) {
            this.data = data;
            this.prev = prev;
            this.next = next;
        }

    }

}

但不论增删还是查询效率其实ArrayList更高,因为每次LinkedList添加元素时都会创建一个对象

你可能感兴趣的:(java,python,算法)