【Java基础13】单列集合Collection

1. 集合

集合与数组类似,都是一个容器将一些元素存放在一起。不同的是数组长度和类型是确 定的,集合是可以初始化之后改变的。数组类型可以是基础类型也可以是引用类型,集 合只能是引用类型。

2. 集合体系

集合主要分为两大类:①单列集合Collection ②双列集合Map

  • 单列集合:类似数组,每个元素只包含一个值。
  • 双列集合:类似二维数组,每个元素包含键值对。

3. 单列集合的体系

常用集合实现类如下图:

【Java基础13】单列集合Collection_第1张图片

List:元素有序,重复和有索引。

  • ArrayList和LinkedList:有序、重复和有索引

Set:元素无序,不重复和无索引。

  • HashSet:无序,不重复和无索引
  • TreeSet:按照大小排序,不重复和无索引
  • LinkedHashSet:有序、不重复和无索引

集合特点:

  • 集合存储的都是引用类型,不可是基础类型,如果保存基础类型需要用包装类。
    <类型>,这个类型被称之为泛型,泛型只能是引用类型。泛型的使用之后补充。

4. 常用方法

Collection是所有单列集合的基类,他的功能是所有单列集合需要实现的,同时单列 集合也可以扩展自己的功能。不同集合也会有自己独立的功能。

方法 说明
public boolean add(E e) 把给定的对象添加到当前集合中
public void clear() 清空集合中所有的元素
public boolean remove(E e) 把给定的对象在当前集合中删除
public boolean contains(Object obj) 判断当前集合中是否包含给定的对象
public boolean isEmpty() 判断当前集合是否为空
public int size() 返回集合中元素的个数。
public Object[] toArray() 把集合中的元素,存储到数组中

5. List

这是集合下一个大的分支,有序、可重复和有索引,这是这一大类主要的特点。

  • 有序:存储和取出的元素顺序一致
  • 重复:存储的元素可以出现相同的
  • 索引:可以通过索引直接找到对应元素

5.1 创建语法

// 例如
ArrayList arrayList=new ArrayList();
// jdk1.7之后省略
        ArrayList arrayList=new ArrayList<>();

5.2 List集合遍历

集合除了有存储功,还有增删改查功能。

5.2.1 for循环遍历

下面通过size方法获得长度,进行for循环便可以遍历所有元素了。

public class ListForTest {
    public static void main(String[] args) {
        // 创建单列集合
        ArrayList arrayList = new ArrayList<>();
        // 新增元素
        arrayList.add(95);
        arrayList.add(55);
        arrayList.add(13);
        arrayList.add(5);

        // 通过下标遍历
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.println(arrayList.get(i));
        }
    }
}

5.2.2 增强for循环遍历

// 格式
for(元素类型 变量名:集合变量){
        ...
        }
public class ListForTest2 {
    public static void main(String[] args) {
        // 创建单列集合
        ArrayList arrayList = new ArrayList<>();
        // 新增元素
        arrayList.add(95);
        arrayList.add(55);
        arrayList.add(13);
        arrayList.add(5);

        // 增强for循环
        for (Integer integer : arrayList) {
            System.out.println(integer);
        }
    }
}

5.2.3 迭代器

这个类代表集合中的元素,集合中通过内部类实现Iterator。获得到的迭代器默认是 指向0索引的。

public class ListIterableTest {
    public static void main(String[] args) {
        // 创建单列集合
        ArrayList arrayList = new ArrayList<>();
        // 新增元素
        arrayList.add(95);
        arrayList.add(55);
        arrayList.add(13);
        arrayList.add(5);

        Iterator iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

Iterator常用方法如下:

方法 说明
Iterator iterator(); Collection集合方法,返回迭代器
boolean hasNext() 获得当前位置是否有元素,存在返回true ,不存在返回false
E next() 获得当前位置元素并指向下一个元素,如果有的话,注意越界

5.2.4 Lambda表达式循环

通过Lambda表达式来实现集合的循环

// 示例
public class ListForEachTest {
    public static void main(String[] args) {
        // 创建单列集合
        ArrayList arrayList = new ArrayList<>();
        // 新增元素
        arrayList.add(95);
        arrayList.add(55);
        arrayList.add(13);
        arrayList.add(5);

        // forEach循环
        arrayList.forEach(new Consumer() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });

        // Lambda表达式
        arrayList.forEach(i -> System.out.println(i));
    }
}

5.3 各个实现类特点

List特有的方法:

方法 说明
void add(int index,E element) 在指定位置插入元素
E remove(int index) 指定位置移除元素
E set(int index,E element) 修改指定位置元素
E get(int index) 获得指定位置元素

ArrayList:

  • 底层基于可变数组实现的,查询快增删较慢

LinkedList:

  • 底层基于双向链表实现的,查询慢增删较快

LinkedList特有的方法:

方法 说明
public void addFirst(E e) 在列表首部插入
public void addLast(E e) 指定位置插入尾部
public E getFirst() 获得首部元素
public E getLast() 获得尾部元素
public E removeFirst() 移除首部元素并返回
public E removeLast() 返回尾部元素并移除

5.4 存储自定义类型

自定义类型进行存储。

public class ListTest {
    public static void main(String[] args) {
        // Book类查看文章最后源码地址
        ArrayList arrayList = new ArrayList<>();
        arrayList.add(new Book("三体", "刘慈欣"));
        arrayList.add(new Book("平凡的世界", "路遥"));
        // 新增两次相同也可以的
        arrayList.add(new Book("活着", "余华"));
        arrayList.add(new Book("活着", "余华"));

        // 遍历
        for (Book book : arrayList) {
            System.out.println(book);
        }
    }
}

6. Set

这是集合中的第二大分支,主要特点是无序、不可重复和无索引。

6.1 格式

同集合List一样的格式

HashSet hashSet=new HashSet<>();

6.2 Set遍历

因为没有索引,所以除了通过长度循环外,其他的循环与List一致。

通过遍历显示可以看出,AA只被输出一次,所以Set集合中不能出现重复的。

public class SetForTest {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hashSet = new HashSet<>();
        // 新增元素(因为不可重复,只能新增一次,重复新增只会)
        hashSet.add("AA");
        hashSet.add("BB");
        hashSet.add("CC");
        hashSet.add("AA");

        // 增强的for循环
        for (String s : hashSet) {
            System.out.println(s);
        }

        // 迭代器
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        // forEach循环
        hashSet.forEach(new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        // forEach加Lambda
        hashSet.forEach(s-> System.out.println(s));
    }
}

6.3 各个实现类的特点

HashSet:无序、不重复和无索引,底层使用的是哈希表。
LinkedHashSet:有序、不重复和无索引,底层是哈希表加双向列表
TreeSet:排序、不重复和无索引,红黑树

注意:_关于底层数据结构将在之后进行讲解_

6.4 常用子类示例

public class Dog {
  private String name;
  private int age;

  public Dog() {
  }

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

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return "Dog{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
  }
}
  1. HashSet
public class HashSetTest {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet<>();
        hashSet.add(new Dog("旺财", 18));
        hashSet.add(new Dog("旺财", 18));

        // 输出可以看见,会有两个相同的元素显示出来,按照不可重复原理,这是不正确的。那么问题出现在哪了。
        for (Dog dog : hashSet) {
            System.out.println(dog);
        }
    }
}

如果对比就不必须实现equals方法,这样的话才可以不出现重复,在自定义类中重写equals和hashCode

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

@Override
public int hashCode() {
    return Objects.hash(name, age);
}
  1. LinkedHashSet
public class LinkedHashSetTest {
    public static void main(String[] args) {
        LinkedHashSet linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add(new Dog("旺财", 19));
        linkedHashSet.add(new Dog("小强", 20));

        for (Dog dog : linkedHashSet) {
            System.out.println(dog);
        }
    }
}
  1. TreeSet
public class TreeSetTest {
    public static void main(String[] args) {
        // 创建TreeSet需要实现排序方法,这里是倒序排列
        TreeSet treeSet = new TreeSet<>((o1, o2) -> o1.getAge() - o2.getAge());

        treeSet.add(new Dog("张三", 20));
        treeSet.add(new Dog("李四", 18));
        treeSet.add(new Dog("王二", 19));

        for (Dog dog : treeSet) {
            System.out.println(dog);
        }
    }
}

本章结束,用于个人学习和小白入门,大佬勿喷!希望大家多多点赞收藏支撑支撑!

源码 【GitHub】 【码云】

你可能感兴趣的