容器 - 集合Collection,列表List,集Set【附源码】

(所有源码均在:https://github.com/zongzhec/JavaPractise

目录

集合概述

集合 Collection

Collection概述

Collection常用方法 (即:增删查改)

源码

列表 List

List 概述

List 常用方法(增删查改+遍历)

源码

List 常见的实现类

Set 集

Set 概述

Set 常见实现

Set 常用方法


集合概述

集合包含很多种容器,每种容器有不同的优缺点。
实际开发中,数据存储可能需要包含以下特点或组合:
1. 有序/无序
2. 可以重复/不能重复
3. 一对一/一对多
JDK在(1)数组,和(2)链式结构的基础上,设计出了很多的容器类型。主要有两大类:
1. Collection:一组对象。
2. Map:键值对

在本文中,我们会一一讨论Collection,List,以及Set的常用方法和注意事项。

常用方法主要包括:增、删、查、改,和遍历

 

集合 Collection

Collection概述

java.util.Collection是层次结构中的根接口,把对容器的操作标准化,比如增删查改。
有一些Collection允许有重复的元素,而另一些则不允许。有一些Collection是有序的,而另一些无序。
因此JDK 不提供此接口的任何直接实现,而是提供更具体的子接口实现,如Set,List等。

Collection常用方法 (即:增删查改)

1. 添加
    1.1. add(Object obj)
    1.2. addAll(Collection other)
2. 删除
    2.1. remove
    2.2. removeAll(): 删除交集
    2.3. clear(): 清空
3. 查询/遍历
    跟借口中没有提供获取一个元素的方法。
    3.1. toArray()
    3.2. isEmpty()
    3.3. foreach
4. 修改:
    根接口中没提供set()方法
    4.1. contains()
    4.2. containsAll(): 判断other中的元素是否都在当前集合中。
5. 其他
    5.1. retainAll(other): 保留交集

源码

package zongzhe.java_basic.data_structure.collection;

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

/**
 * 用于理解Collection的常用方法。
 */
public class CollectionDemo {

    public static void main(String[] args) {

        checkAddFunctions(); // 添加
        checkDeleteFunctions(); // 删除
        checkIterateFunctions(); // 遍历
        checkOtherFunctions(); // 其他


    }

    private static void checkAddFunctions() {
        Collection c = new ArrayList(); // ArrayList是Collection子接口List的实现类。
        c.add("1st element");
        c.add("2nd element");

        Collection other = new ArrayList();
        other.add("3rd element");
        other.add("4th element");

        c.addAll(other);
        System.out.println("c size: " + c.size());
    }

    private static void checkDeleteFunctions() {
        Collection c = new ArrayList();
        c.add("1st element");
        c.add("2nd element");

        Collection other = new ArrayList();
        other.add("1st element");
        other.add("4th element");

        c.removeAll(other);
        System.out.println("c size: " + c.size());
    }

    private static void checkIterateFunctions() {
        Collection c = new ArrayList();
        c.add("1st element");
        c.add("2nd element");

        for (Object obj : c) {
            System.out.println(obj);
        }
    }

    private static void checkOtherFunctions() {
        Collection c = new ArrayList();
        c.add("1st element");
        c.add("2nd element");

        Collection other = new ArrayList();
        other.add("1st element");
        other.add("4th element");

        c.retainAll(other);
        System.out.println("c size: " + c.size());
    }
}

 

列表 List

List 概述

特征:有序,可重复

List 常用方法(增删查改+遍历)

1. 所有collection的常用方法,因为List继承了Collection
2. 额外的方法,大多跟index有关
    2.1. 增: add(int index, E element), addAll(int index, Collection): 在指定位置插入一个或多个元素。
    2.2. 删: remove(int index)
    2.3. 查: get(int index), indexOf(Object o), lastIndexOf(Object o)
    2.4. 改: set(int index, E element): 注意,原Collection根接口中没提供set()方法
    2.5. 遍历:ListIterator,是Iterator的子接口,在其基础上增加了方向,同时增加了set和add方法。

源码

package zongzhe.java_basic.data_structure.collection;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListDemo {

    public static void main(String[] args) {

        checkAddFunctions(); // 增
        checkRemoveFunc(); // 删
        checkQueryFunc(); // 查
        checkSetFunc(); // 改
        checkIterFunc(); // 遍历

    }

    private static void checkAddFunctions() {
        List list = new ArrayList();
        list.add("one element");
        list.add(0, "another element"); // 在指定位置添加元素

        List list2 = new ArrayList();
        list2.add("list2 element1");
        list2.add("list2 element2");

        list.addAll(1, list2); // 在指定位置添加集合,千万不要写成list.add(1, list2)

        for (Object o : list) {
            System.out.println("element: " + o);
        }
    }

    private static void checkRemoveFunc() {
        List list = new ArrayList();
        list.add("one element");
        list.add("another element");

        list.remove(0);

        for (Object o : list) {
            System.out.println("element: " + o);
        }
    }

    private static void checkSetFunc() {
        List list = new ArrayList();
        list.add("one element");
        list.add("another element");

        list.set(0, "updated element");

        for (Object o : list) {
            System.out.println("element: " + o);
        }
    }

    private static void checkQueryFunc() {
        List list = new ArrayList();
        list.add("one element");
        list.add("another element");
        list.add("another element");

        System.out.println("value of first index: " + list.get(0));
        System.out.println("first index of another element: " + list.indexOf("another element"));
        System.out.println("last index of another element: " + list.lastIndexOf("another element"));
    }

    private static void checkIterFunc() {
        List list = new ArrayList();
        list.add("one element");
        list.add("another element");
        list.add("third element");

        ListIterator iter = list.listIterator();
        // 往后遍历
        while (iter.hasNext()) {
            Object next = iter.next();
            System.out.println(next);
        }

        // 往前遍历
        iter = list.listIterator(list.size()); // 看到index,可以意识到我们其实可以从任意位置开始遍历
        while (iter.hasPrevious()) {
            Object prev = iter.previous();
            System.out.println(prev);
        }
    }
}

List 常见的实现类

1. Vector:动态数组,旧版本,线程安全
2. ArrayList: 动态数组,新版本,线程不安全
3. LinkedList:双向列表、双端队列,内部实现是列表
4. Stack:栈,是Vector的子类,先进后出,已经不建议使用,因为其功能被LinkedList覆盖
    push(压栈),pop(弹栈,移除栈顶元素),peek(返回栈顶元素,但不移除)

 

Set 集

Set 概述

不可重复的,无序的(不要拿LinkedHashSet抬杠)
如何保证两个元素不重复?——重写equals方法,而TreeSet是依据元素的“大小”顺序。

Set 常见实现

1. HashSet:完全无序
2. TreeSet:有大小顺序,和添加顺序无关(既然有“大小”顺序,那么就要求元素实现了Comparable)
3. LinkedHashSet:是HashSet的子类,但具备了“添加顺序”的功能。因此遍历时可以保证添加顺序,而存储和添加顺序无关,同时也导致效率比HashSet低。

Set 常用方法

基本是直接调用Collection的方法。但是在查重上有判断。换言之,如果你传入了自定义类型,则需要重写equals方法,来保证Set 不会加入重复元素。见如下代码。

源码

package zongzhe.java_basic.data_structure.collection;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

public class SetDemo {

    public static void main(String[] args) {
        checkAddFunc(); // 增
        checkCustomTypeAddFunc(); // 设定自定义类型,深入了解Set的功能
    }

    private static void checkAddFunc() {
        Set set = new HashSet();
        set.add("a"); // 此处是Collection的add方法
        set.add("z");
        set.add("2");
        set.add("a");
        set.add("b");
        printSet(set); // 从打印结果看,没有顺序

        Set treeSet = new TreeSet();
        treeSet.add("a");
        treeSet.add("z");
        treeSet.add("c");
        treeSet.add("a");
        treeSet.add("b");
        printSet(treeSet); // 从打印结果看,为按照字符顺序输出

    }

    private static void checkCustomTypeAddFunc() {
        Set set = new HashSet();
        set.add(new Person(1, 18, "person a")); // 添加自定义类型
        set.add(new Person(2, 18, "person b"));
        set.add(new Person(3, 18, "person c"));
        set.add(new Person(4, 18, "person d"));
        set.add(new Person(4, 18, "person d"));
        printSet(set); // 从打印结果看,且仅有一个person d

        Set treeSet = new TreeSet();
        treeSet.add(new Person(1, 18, "person a")); // 添加自定义类型
        treeSet.add(new Person(2, 18, "person b"));
        treeSet.add(new Person(3, 18, "person c"));
        treeSet.add(new Person(4, 18, "person d"));
        treeSet.add(new Person(4, 18, "person e"));
        printSet(treeSet); // 从打印结果看,Person按id排序,且person e 没有被添加进去
    }

    private static void printSet(Set set) {
        System.out.println("printing set");
        for (Object o : set) {
            System.out.println(o);
        }
    }
}

class Person implements Comparable {
    private int id;
    private int age;
    private String name;

    public Person(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id &&
                age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, age, name);
    }

    @Override
    public int compareTo(Object o) {
        Person person = (Person) o;
        return this.id - person.id;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值