Java集合体系(一)-- Collection体系

1、Java集合体系

  Java集合体系主要由两个接口派生而出:Collection和Map。本篇博文主要讲述Collection的继承体系,Collection是一个接口,定义了一系列的集合操作方法,其实现类主要是重写抽象方法和定义自己特定的方法。该体系的实现类都是直接或间接实现Collection的三个子接口:List、Queue、Set。我们常用的实现类主要有ArrayList、LinkedList、TreeSet、HashSet。
Collection体系继承树

2、List接口及其实现类

2.1、List

List接口的主要方法如下:
public void add(int index, E element) :将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

        //1.使用多态思想,创建List集合对象
        List<String> list = new ArrayList<>();
        //2.往尾部添加制定元素
        boolean a = list.add("小明");
        boolean b = list.add("小红");
        boolean c = list.add("小刚");
        //3.输出集合
        System.out.println("list = " + list);
        //4.删除指定索引的元素,并返回被删除的元素
        String removeElement = list.remove(2);
        System.out.println("removeElement = " + removeElement);
        //5.获取指定位置的元素
        String getElement = list.get(1);
        System.out.println("getElement = " + getElement);
        //6.修改指定位置的元素
        String setElement = list.set(1, "小严");
        System.out.println("setElement = " + setElement);

2.2、ArrayList

  ArrayList 集合数据存储的结构是数组(关于数组与链表的区别,请查询数据结构)。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。想对ArrayList深入了解的,应该查看它的源码。
  查看源码可知,类中定义了private static final int DEFAULT_CAPACITY = 10;与private int size;其中DEFAULT_CAPACITY表示初始容量为10,size表示当前列表的存储的数据数量。类中有多个构造方法,若是指定容量,则使用指定的数字创建ArrayList,否则使用默认数量10为初始化容量。
  其他的一些常用方法均可根据方法名与形参列表了解用法,若是想深入了解就查看源码。

2.3、LinkedList

  LinkedList 集合数据存储的结构是链表。元素增删快,查找慢。
在这里插入图片描述
  实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。
public void addFirst(E e) :将指定元素插入此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第一个元素。
public E getLast() :返回此列表的最后一个元素。
public E removeFirst() :移除并返回此列表的第一个元素。
public E removeLast() :移除并返回此列表的最后一个元素。
public E pop() :从此列表所表示的堆栈处弹出一个元素。
public void push(E e) :将元素推入此列表所表示的堆栈。
public boolean isEmpty() :如果列表不包含元素,则返回true。
  由于LinkedList特殊的结构和方法,我们可以利用它来定义栈和队列,具体实现代码如下

public class Stack<E> {
    //定义一个linkedlist集合
    private LinkedList<E> list = new LinkedList<>();

    //入栈,链表的头为栈顶
    public void push(E e) {
        list.addFirst(e);
    }

    //出栈,并返回被出栈的元素
    public Object pop() {
        E e = list.removeFirst();
        return e;
    }

    //栈的大小
    public int size() {
        return list.size();
    }

    //查看栈顶元素
    public E peak(){
        return list.getFirst();
    }

	//集合是否为空
    public boolean isEmpty(){
        int size = this.size();
        if (size == 0){
            return true;
        }
        return false;
    }

    public String toString(){
        return list.toString();
    }
}
public class Quene<E> {
    private LinkedList<E> list = new LinkedList<>();

    //入队,链表的头为队头
    public void push(E e) {
        list.addLast(e);
    }

    //出队
    public E pop() {
        return list.removeFirst();
    }

    //队列的大小
    public int size() {
        return list.size();
    }

    //查看队头元素
    public E peak(){
        return list.getFirst();
    }

    //查看队尾元素
    public E rear(){
        return list.getLast();
    }

    //队列是否为空
    public boolean isEmpty(){
        int size = this.size();
        if (size == 0){
            return true;
        }
        return false;
    }

    public String toString(){
        String s = list.toString();
        return s;
    }
}

3、Set接口及其实现类

3.1、Set

   Set 接口和 List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不同的是,Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。Set 集合有多个子类,这里我们介绍其中的 HashSet 、LinkedHashSet 这两个集合。

3.2、HashSet

   java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。查看源码可知, HashSet 底层的实现其实是一个 HashMap 支持,只是将其中value固定了,把key作为HashSet的值。HashSet 是根据对象的哈希算法(详情查看数据结构)来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性 的方式依赖于:hashCode 与 equals 方法。要想了解HashSet,应该使用HashSet分别储存Integer类型、String类型、自定义对象类型来研究HashSet。

public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<Integer>();
        set.add(1);
        set.add(3);
        set.add(2);
        set.add(1);
        System.out.println("set = " + set);
    }

结果输出为set = [1, 2, 3],说明元素添加的无序且不重复的。

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        String s1 = new String("aaa");
        String s2 = new String("aaa");
        System.out.println(s1 == s2);//false
        String s3 = new String("ccc");
        String s4 = new String("ddd");
        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        System.out.println("set = " + set);
    }

结果输出为set = [aaa, ccc, ddd]。由于String类型是引用类型,所以s1与s2的地址不同,但由于String重写了equals方法,所以HashSet认为二者是相同的。

public class Student {
    //未重写equals和hashCode方法
    private int age;     //
    private String name;      //

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

	public static void main(String[] args) {
        HashSet<Student> set = new HashSet<>();
        Student stu1 = new Student(23, "小明");
        Student stu2 = new Student(23, "小明");
        Student stu3 = new Student(24, "小红");
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        System.out.println("set = " + set);
    }
}

  定义的Student没有重写equals方法,所以HashSet判断两个student对象是否相同是根据地址值是否相同来判定的(Object类的原始equals方法)。所以结果输出为set = [Student{age=23, name=‘小明’}, Student{age=23, name=‘小明’}, Student{age=24, name=‘小红’}]。
  利用IDEA生成equals和hashCode方法,得出的结果为set = [Student{age=23, name=‘小明’}, Student{age=24, name=‘小红’}]。

3.3、LinkedHashSet

  我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢? 在HashSet下面有一个子类LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构,保证了存取一致。其它的用法与HashSet几乎一致。

3.4、TreeSet

  TreeSet底层是二叉树,可以对对象元素进行排序,但是自定义类需要实现comparable接口,重写comparaTo() 方法。TreeSet 可以保证对象元素的唯一性(并不是一定保证唯一性,需要根据重写的compaaTo方法来确定)。下面演示存储integer类型和自定义对象类型。

public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(5);
        set.add(1);
        set.add(4);
        System.out.println("set = " + set);
    }

结果输出set = [1, 2, 3, 4, 5]

public class Student implements Comparable{
    private int age;     //
    private String name;      //

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

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

    @Override
    public int compareTo(Object o) {
        Student student = (Student)o;//向下转型
        return this.age - student.age;//按年龄排序
    }

    public static void main(String[] args) {
        TreeSet<Student> set = new TreeSet<>();
        set.add(new Student(23, "小明"));
        set.add(new Student(24, "小明"));
        set.add(new Student(25, "小明"));
        System.out.println("set = " + set);
    }
}

4、Queue

Queue是实现队列的类,但现在使用很少了。重点还是在List和Set上

有错误的地方敬请指出!觉得写得可以的话麻烦给个赞!欢迎大家评论区或者私信交流!

发布了30 篇原创文章 · 获赞 72 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Orange_minger/article/details/104554670
今日推荐