集合(1)

集合

集合是一个可以存放引用数据类型的容器,大小不固定。 集合的顶级接口是Collection

<E>``` :泛型,就是集合中存放的数据类型。只能是引用数据类型,不能是基本数据类型

## 集合特点

提供一种存储空间可变的存储模型,存储数据的容量可以发生改变

在数组装满的情况下 自动扩容
1.数组
2.链表
3.树
4.队列

## 集合常用方法

```java
import java.util.ArrayList;
import java.util.Collection;

public static void main(String[] args) {
    //ArrayList<>()方法
    Collection
<String> collection = new ArrayList<>();
    //添加元素
    collection.add("123");
    collection.add("456");

    //清空集合
    collection.clear();

    //判断是否包含某一元素
    //contains()
    System.out.println(collection.contains("123"));
    System.out.println(collection);

    //判断集合是否为空
    //isEmpty()
    System.out.println(collection.isEmpty());

    //获取集合中的元素个数
    System.out.println(collection.size());

    //把集合转换成数组
    Object[] objects = collection.toArray(new String[0]);
    for (String object : objects) {
        System.out.println(object);
    }
    System.out.println(collection);
}

List 接口

特点:

  1. 有序
  2. 可以存放重复的元素
  3. 方法中有索引
import java.util.ArrayList;

public static void main(String[] args) {
    //List接口
    List
<String> list = new ArrayList<>();
    //添加数据
    list.add("java");
    //插入元素
    list.add(2, "JAVA");
    //根据索引获取元素
    String s = list.get(3);
    System.out.println(s);

    //获取元素首次出现的索引
    int index = list.indexOf("java");
    System.out.println(index);

    //获取元素最后一次出现的索引
    int JAVA = list.lastIndexOf("JAVA");
    System.out.println(JAVA);

    //根据索引删除元素
    String remove = list.remove(2);
    System.out.println(remove);

    //修改给出索引处的元素
    list.set(2, "C++");

    //截取子列表 包头不包尾
    List
<String> strings = list.sublist(1, 2);
    System.out.println(strings);
    System.out.println(list);
}

ArrayList

JDK封装好的ArrayList/Map/Set

原生数组存放数据 在开始定义时容量固定 因此会无法存放

特点:

底层的数据结构是数组,因此内存是连续的

ArrayList的查询速度相对更快

ArrayList的增加和删除速度相对慢

ArrayList是线程不安全的集合

调用无参构造,会创建一个长度为0的Object类型的数组

当第一次调用add方法时,会创建一个长度为10的数组。

ArrayList默认内容是10

扩容 = 原本容量 + 原本容量 / 2

当调用有参构造指定初始化容量时,指定多少就是多少

实例

    import java.util.ArrayList;

public class TestDemo {
    public static void main(String[] args) {
        /**
         * new ArrayList<泛型>
         */
        list
<String> arrayList = new ArrayList<String>();//集合容器中只能存入 String 类型
        //arrayList 对象名称
        arrayList.add("mayikt");
    }
}

方法实例

import java.util.ArrayList;

public static void main(String[] args) {
    // list接口

    List
<String> list = new ArrayList<>(16);
    //添加数据
    list.add("java");
    list.add("C");
    list.add("C#");
    list.add(".net");
    list.add("golang");
    list.add("python");
    list.add("python");

    //插入元素
    list.add(2, "PHP");

    //根据索引获取元素
    String s = list.get(3);
    System.out.println(s);

    //获取元素首次出现的索引
    int index = list.indexOf("丁真");
    System.out.println(index);

    // 获取元素最后一次出现的索引
    int python = list.lastIndexOf("python");
    System.out.println(python);
    // 根据索引删除元素
    String remove = list.remove(2);
    System.out.println(remove);

    // 修改指定索引处的元素
    list.set(1, "怪0");

    // 截取子列表  包头不包尾
    List
<String> strings = list.subList(1, 5);
    System.out.println(strings);
    System.out.println(list);
}

功能实现

实现ArrayList

import java.util.Arrays;

public class ArrayListDemo {
    private String[] data;
    private int size = 0;

    public ArrayListDemo() {
        data = new String[0];
    }

    private void grow() {
        if (data.length == 1) {
            data = Arrays.copyOf(data, data.length + 1);
        } else data = Arrays.copyOf(data, data.length + (data.length &gt;&gt; 1));
    }

    private void isIndexOutOfBound(int index) {
        if (index &lt; 0 || index &gt;= data.length) throw new IndexOutOfBoundsException();
    }

    /*
     * 添加元素
     * */

    public void add(String str) {
        if (data.length == 0) data = new String[10];
        //判断是否需要扩容
        if (size &gt;= data.length) {
            grow();
        }
        data[size] = str;
        size++;
    }

    /*
     * 插入元素
     * */

    public void insert(int index, String str) {
        //判断索引是否越界
        isIndexOutOfBound(index);
        //判断是否需要扩容
        //两种情况,插入在数组内,插入在数组最后一个
        if (size &gt;= data.length) {
            grow();
        }
        //方法一 循环
//        for(int i = 0; i &lt; size; i++) {
//            data[i+1] = data[i];
//        }
        //方法二 arraycopy()
        System.arraycopy(data, index, data, index + 1, size - index);

        data[index] = str;
        size++;

    }
    //删除指定元素

    public void remove(int index) {
        //判断索引是否越界
        isIndexOutOfBound(index);
        //方式一 循环
//        for (int i = 0; i &lt; index; i++) {
//            data[i] = data[i + 1];
//        }
        //方法二 arraycopy()
        System.arraycopy(data, index + 1, data, index, size - index - 1);
        size--;
    }

    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(&quot;[&quot;);
        for (int i = 0; i &lt; size; i++) {
            if (i != size - 1) stringBuffer.append(data[i]).append(&quot;,&quot;);
            else {
                stringBuffer.append(data[i]);
            }
        }
        stringBuffer.append(&quot;]&quot;);
        return stringBuffer.toString();
    }
}

LinkedList

  • LinkedList底层数据结构是双向不循环链表
  • LinkedList的内存是不连续的
  • LinkedList查询相对慢
  • LinkedList增删相对快
  • LinkedList线程不安全

实现LinkedList

import java.util.Objects;

public class LinkedListDemo {
    private int size;
    private Node first;
    private Node last;

    private class Node {
        String item;
        Node next;
        Node prev;

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

    }

    private void isIndexOutOfBound(int index) {
        if (index &gt; size || index &lt; 0) throw new IndexOutOfBoundsException();
    }

    private Node getNode(int index) {
        Node targetNode = first;
        for (int i = 0; i &lt; index; i++) {
            targetNode = targetNode.next;
        }
        return targetNode;
    }

    /*
     * 添加元素方法
     * */

    public void addNode(String str) {
        //添加元素分两种情况
        //1. 第一次添加,头结点和尾结点相同
        //2. 第n次添加,需要把新添加的结点设为尾结点

        //创建结点

        Node node = new Node(str, null, null);
        if (size == 0) {
            first = node;
        } else {
            last.next = node;
        }
        last = node;
        size++;
    }

    /*
     * 插入元素
     * @param index 插入的索引
     * @param str 插入的内容
     * */

    public void insert(int index, String str) {
        //判断索引是否越界
        isIndexOutOfBound(index);
        //双向链表插入分三种情况,头部,中间,尾部

        //插入尾部
        if (index == size) {
            addNode(str);
        }
        Node newnode = new Node(str, null, null);
        if (size == 0) {
            //插入头部
            newnode.next = first;
            first.prev = newnode;
            first = newnode;
        } else {
            //插入中间,需要先寻找索引处的结点
            //通过封装好的方法,遍历链表找到对应需要插入的结点位置
            Node nextnode = getNode(index);
            //找到的后结点指向的前结点的后结点为新结点
            nextnode.prev.next = newnode;
            //新结点指向的前结点为前结点
            newnode.prev = nextnode.prev;
            //新节点指向的后结点为后结点
            newnode.next = nextnode;
            //后结点指向的前结点为新结点
            nextnode.prev = newnode;
        }
        size++;
    }

    //删除元素
    public void remove(int index) {
        isIndexOutOfBound(index);
        //删除元素分三种情况,删除头节点 尾结点 中间结点

        //删除头部结点
        if (index == 0) {
            first = first.next;
            first.prev = null;
        }
        //删除尾部结点
        else if (index == size - 1) {
            last = last.prev;
            last.next = null;
        }
        //删除中间结点
        else {
            Node targetNode = getNode(index);
            targetNode.prev.next = targetNode.next;
            targetNode.next.prev = targetNode.prev;
        }
        size--;
    }

    /*
     * 查询指定元素首次出现的索引
     * 按字符串查找
     * */
    public int indexOf(String str) {
        Node node = first;
        for (int i = 0; i &lt; size; i++) {
            if (Objects.equals(node.item, str))
                return i;
            node = node.next;
        }
        return -1;//如果未找到返回-1
    }

    /*
     *删除指定元素
     * 调用查找指定元素的方法
     * 调用删除元素的方法
     * */

    public void remove(String str) {
        int i = indexOf(str);
        if (i != -1) {
            remove(i);
        }
    }

    /*
     * 判断链表中是否包含某元素
     * */

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

LinkedList的增删改查操作图解

个人理解

主要思想是利用找到的新结点的后结点的指针定位新结点的前结点

![第0步.png](https://www.neet0316.com/wp-content/uploads/2025/12/%E7%AC%AC0%E6%AD%A5.png

先更改前结点指向的后结点和新结点指向的前结点(第一步和第二步)

![第1步.png](https://www.neet0316.com/wp-content/uploads/2025/12/%E7%AC%AC1%E6%AD%A5.png

![第2步.png](https://www.neet0316.com/wp-content/uploads/2025/12/%E7%AC%AC2%E6%AD%A5.png

再更改后结点指向的前结点和新结点指向的后结点(第三步和第四步)

![第3步.png](https://www.neet0316.com/wp-content/uploads/2025/12/%E7%AC%AC3%E6%AD%A5.png

![第4步.png](https://www.neet0316.com/wp-content/uploads/2025/12/%E7%AC%AC4%E6%AD%A5.png

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇