Java基础二十四(集合框架)

集合框架

Java 集合框架提供了一套性能优良、使用方便的接口和类,他们都位于 java.util 包中。Java 集合框架由3大类接口构成(Map接口List接口Set接口)。
在这里插入图片描述

1. lterable 接口

java.lang.lterable 接口是 Java 标准库中的一个接口,用于表示可迭代的集合类。实现了 lterable 接口的类可以使用 Java 中的 for-each 循环来遍历其元素,使其具有可迭代的特性。

返回值类型方法名描述
Iterator<E>iterator()返回一个迭代器,用于遍历集合中的元素。
voidforEach(Consumer<? super E> action)对集合中的每个元素执行给定操作。
Spliterator<E>spliterator()返回一个拆分器,用于对集合中的元素进行分割迭代。

例子

import java.util.*;

public class VectorExample {
    public static void main(String[] args) {
        Vector<Student> students = new Vector<Student>();

        students.add(new Student("犯困桃子", 10, 11));
        students.add(new Student("小羊呆呆", 20, 11));
        students.add(new Student("中科盛康人才", 5, 11));
        students.add(new Student("小羊", 30, 11));
        students.add(new Student("盛康人才", 1, 11));

        // 比较排序
        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return Integer.compare(s1.getMath(), s2.getMath());
            }
        });
		// 使用 for-each迭代输出
        for (Student student : students) {
            System.out.println(student);
        }

        students.get(3).setName("三娃");  // 设置名称
        students.insertElementAt(new Student("五娃", 20, 17), 4);  // 指定下标插入
        System.out.println(students.size());
        students.remove(students.size() - 1);  // 删除最后一个元素
		// 使用 iterator() 输出
        Iterator<Student> iterator = students.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

2. Collection 接口

Collection 接口是 Java.util 包下的一个接口,用于表示一组对象是集合。它是 Java 集合框架中的根接口,继承了 lterable 接口,因此它可以用于遍历集合中的元素。Collection 接口提供了一组通用的方法,用于对集合进行基本的操作。

方法名返回值描述
add(E e)boolean添加元素
addAll(Collection<? extends E> c)boolean将集合c中的所有元素添加到此集合中
clear()void清除所有元素
contains(Object o)boolean集合中是否包含指定元素
containsAll(Collection<?> c)boolean集合是否包含指定集合中的所有元素
isEmpty()boolean集合是否为空
iterator()Iterator返回集合的迭代器
remove(Object o)boolean删除集合中的某个元素
removeAll(Collection<?> c)boolean删除集合中与指定集合中相同的所有元素
retainAll(Collection<?> c)boolean保留集合中与指定集合中相同的元素
size()int返回集合中的元素数
toArray()Object[]返回包含集合中所有元素的数组

Collection 接口实现的类包括常见的 ArrayListLinkedListHashSetTreeSetLinkedHashSet 等。

2.1 队列(Queue)

public interface Queue<E>
extends Collection<E>

设计用于在处理之前保留元素的集合。 除了基本的 Collection 操作之外,队列还提供额外的插入,提取和检查操作,不可以存 null
下面是常用的Queue接口方法及其描述:

方法名返回值类型描述
add(E e)boolean将指定元素插入此队列 。如果队列已满,则会抛出IllegalStateException异常
offer(E e)boolean将指定元素插入此队列 。 如果队列已满,则会返回false
remove()E检索并删除此队列的头部 。如果队列为空,则会抛出NoSuchElementException异常
poll()E检索并删除此队列的头部,如果此队列为空,则返回null
element()E检索但不删除此队列的头部 。如果队列为空,则会抛出NoSuchElementException异常
peek()E检索但不删除此队列的头部,如果此队列为空,则返回null
size()int返回队列中的元素数
contains(Object o)boolean如果此队列包含指定元素,则返回true
clear()void移除此队列中的所有元素
toArray()Object[]返回包含此队列所有元素的数组;返回数组按照队列元素排列顺序

上述方法是 Queue 接口中常用的方法,通过实现该接口,并重写其中的方法,即可定义自己的队列实现类。Queue 接口实现的类有很多,例如常用的有 LinkedListArrayDeque 等。

Queue 接口不允许插入 null 元素,也不允许包含重复的元素。

2.2 Deque(双端队列)

public interface Deque<E>
extends Queue<E>

继承了 Queue ,支持两端(首尾)元素插入和移除的线性集合。

方法名返回值类型描述
addFirst(E e)void在双端队列的前面插入元素
addLast(E e)void在双端队列的末尾插入元素,类似于add(E e)
getFirst()E检索但不删除双端队列的第一个元素
getLast()E检索但不删除双端队列的最后一个元素
pop()E删除并返回双端队列的第一个元素
push(E e)void相当于addFirst(E e),在双端队列的前面插入元素
removeFirstOccurrence(Object o)boolean从双端队列中删除第一次出现的指定元素,如果不存在则保持不变
removeLastOccurrence(Object o)boolean从双端队列中删除最后一次出现的指定元素,如果不存在则保持不变

2.3 set(集合)

public interface Set<E>
extends Collection<E>

集合中的对象并不能保存重复的对象,也就是说 Set 接口可以储存一组唯一、无序的对象。
在Java中,Set是一种集合接口,它继承自Collection接口。Set集合的主要属性如下:

  1. 无序性:Set集合中的元素是无序排列的,不会按照插入顺序或者其他特定顺序进行存储。这是因为Set集合通常基于哈希表或红黑树实现,以提供快速的插入、删除和搜索操作。

  2. 唯一性:Set集合中不允许包含重复的元素。当添加重复元素时,Set集合会自动拒绝并保留唯一性。

  3. 不允许使用索引:Set集合没有提供索引访问元素的方法,因为它的元素是无序的。如果需要按索引访问元素,应该使用List集合。

  4. 添加、删除和包含操作的性能较高:由于Set集合通常使用哈希表或红黑树实现,可以在常数时间内执行添加、删除和包含操作。

  5. 允许使用null元素:Set集合允许存储一个null元素。但需要注意,HashSet和LinkedHashSet不保证存储顺序,而TreeSet不允许存储null元素。

常见的Set集合实现类有:

  • HashSet:基于哈希表实现,具有较好的查找性能,不保证元素的存储顺序。
  • LinkedHashSet:基于哈希表和链表实现,按插入顺序保留元素,具有较好的遍历性能。
  • TreeSet:基于红黑树实现,按照元素的自然顺序或者指定的Comparator进行排序。

of 方法和 copyOf ,都是 static 方法返回一个不可修改的 Set 集合。

2.3.1 HashSet 类动态储存数据
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable

实现了 Set 接口,底层实现是 HashMap。不保证迭代顺序,允许 null 元素。

HashSet 的特性:

  1. 非线程安全的
  2. 如果 add 的值已存在( equals方法返回 true ,基本数据类型自动装箱)返回 false
  3. 如果 HashSet 中存的是对象,需要重写此对象类中的 equalshashCode() 方法
  • HashSet内部使用哈希表来存储元素,这使得插入、删除和查找元素的操作效率非常高。如果你需要对集合进行频繁的插入、删除和查找操作,并且不关心元素的顺序,那么HashSet可以提供较好的性能。
  • 当需要存储唯一元素、不关心元素顺序、需要快速的插入、删除和查找操作时,选择HashSet是一个不错的选择。
2.3.2 TreeSet 类动态储存数据
public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable

TreeSet 使用红黑树数据结构来实现元素的排序和储存。TreeSet 中的元素按照自然排序或指定的比较器(Comparator)进行排序,并且不允许重复的元素,不允许 null 元素。

TreeSet 的特性:

  1. 非线程安全
  2. 值必须可比较(元素实现 Comparable 接口、传递 比较器 Comparator 对象)
  3. 不能存 null
  4. 判断是否是重复元素,是按照自然比较/比较器进行比较

如果使用 无参构造 则 Set 集合中的元素要具备可比较行(实现 Comparable 接口)
如果使用 构造(比较器) 则 Set 集合中的元素按照比较器比较顺序排序

TreeSet常用的方法

方法描述返回类型
add(E e)向集合中添加指定元素boolean
remove(Object o)从集合中移除指定元素boolean
contains(Object o)检查集合是否包含指定元素boolean
isEmpty()检查集合是否为空boolean
size()返回集合中元素的数量int
clear()清空集合中的所有元素void
iterator()返回一个迭代器,用于遍历集合中的元素Iterator
first()返回集合中的第一个(最小)元素E
last()返回集合中的最后一个(最大)元素E
lower(E e)返回集合中严格小于指定元素的最大元素E
floor(E e)返回集合中小于或等于指定元素的最大元素E
higher(E e)返回集合中严格大于指定元素的最小元素E
ceiling(E e)返回集合中大于或等于指定元素的最小元素E
headSet(E toElement)返回集合中小于指定元素的部分视图SortedSet
tailSet(E fromElement)返回集合中大于等于指定元素的部分视图SortedSet
subSet(E fromElement, E toElement)返回集合中在指定范围内的部分视图SortedSet

请注意,TreeSetSortedSet接口的实现类,因此它具有一些额外的方法,如 first()last()lower()floor()higher()ceiling()subSet()。这些方法可用于根据元素的自然排序或提供的比较器来执行特定的操作和查询。
示例

import java.util.TreeSet;

public class TreeSetExample {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>();

        // 添加元素到集合中
        treeSet.add(5);
        treeSet.add(10);
        treeSet.add(2);
        treeSet.add(8);
        treeSet.add(3);

        System.out.println("TreeSet: " + treeSet);  // [2, 3, 5, 8, 10]

        // 获取最小元素
        int firstElement = treeSet.first();
        System.out.println("First Element: " + firstElement);  // 2

        // 获取最大元素
        int lastElement = treeSet.last();
        System.out.println("Last Element: " + lastElement);  // 10

        // 获取严格小于指定元素的最大元素
        int lowerValue = treeSet.lower(6);
        System.out.println("Lower Value: " + lowerValue);  // 5

        // 获取小于或等于指定元素的最大元素
        int floorValue = treeSet.floor(5);
        System.out.println("Floor Value: " + floorValue);  // 5

        // 获取严格大于指定元素的最小元素
        int higherValue = treeSet.higher(4);
        System.out.println("Higher Value: " + higherValue);  // 5

        // 获取大于或等于指定元素的最小元素
        int ceilingValue = treeSet.ceiling(5);
        System.out.println("Ceiling Value: " + ceilingValue);  // 5

        // 获取在指定范围内的部分视图
        TreeSet<Integer> subSet = (TreeSet<Integer>) treeSet.subSet(3, 8);
        System.out.println("SubSet: " + subSet);  // [3, 5]
    }
}

2.4 list接口(列表)

有序集合(也称为序列 )。 该集合用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。

List 通常允许重复的元素、允许 null 元素

方法名返回值类型描述
add(int index, E element)void将指定的元素插入此列表中的指定位置
addAll(int index, Collection<? extends E> c)boolean将指定集合中的所有元素插入到此列表中的指定位置
get(int index)E返回此列表中指定位置的元素
indexOf(Object o)int返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回 -1
lastIndexOf(Object o)int返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回 -1
remove(int index)E删除该列表中指定位置的元素,返回被删除的元素
set(int index, E element)E用指定的元素(可选操作)替换此列表中指定位置的元素,返回被替换的值
subList(int fromIndex, int toIndex)List返回此列表中指定的 fromIndex (含)和 toIndex之间的元素集合
default sort(Comparator c)void按照 c 比较器进行自然排序 (JDK 8)
static copyOf(Collection coll)List按照迭代顺序返回一个不可修改的 List (JDK 10)
static of()List返回包含任意数量元素的不可修改列表 (JDK 9)

示例

import java.util.List;
import java.util.Scanner;

public class ListExample01 {
    public static void main(String[] args) {
		// List不可修改
        List commodity = List.of("棉花糖", "气球", "风筝", "饼干", "巧克力");
        Scanner input = new Scanner(System.in);
        System.out.println("请输入你要查询的商品信息");
        String str = input.next();

        if (commodity.contains(str)) {
            String information = (String) commodity.get(commodity.indexOf(str));
            System.out.println(information);
        } else {
            System.out.println("暂时没有这个商品");
        }
    }
}

主要子类: ArrayListLinkedListVectorStack 等。

2.4.1 Vector 类动态储存数据

Vector 类是一种动态数组,它可以自动扩展和缩小数组的大小,实现了 List 接口,且所有的方法都是同步的(线程安全的),适用于多线程环境中的操作。
Vector 类的特点:

  1. 动态数组:Vector的大小可以根据需要自动增长或减小。当添加元素超过当前容量时,Vector会自动重新分配内部数组的大小以容纳更多的元素。默认大小为10,扩容为*2
  2. 线程安全:Vector是线程安全的,意味着多个线程可以同时对Vector进行读取和写入操作,而不会导致数据不一致的问题。Vector中的方法都使用了同步关键字来确保线程安全性。
  3. 支持随机访问:Vector类支持通过索引值来访问集合在的元素,具有常数时间度的随机访问特性。
  4. 可以包含重复元素
  5. 可以插入 null
import java.util.Comparator;
import java.util.Iterator;
import java.util.Vector;

public class VectorExample02 {
    public static void main(String[] args) {
        Vector<Student> students = new Vector<Student>();

        students.add(new Student("犯困桃子", 10, 91));
        students.add(new Student("小羊呆呆", 20, 72));
        students.add(new Student("中科盛康人才", 5, 35));
        students.add(new Student("小羊", 30, 50));
        students.add(new Student("盛康人才", 1, 11));
        students.add(new Student("张三", 23, 90));
        students.add(new Student("李四", 24, 80));
        students.add(new Student("王五", 43, 70));
        students.add(new Student("赵六", 24, 80));
        students.add(new Student("田七", 25, 50));

        students.sort(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return (sum(o1) - sum(o2)) * -1 ;
            }
        });

//        Iterator<Student> iterator = students.iterator();
//        while (iterator.hasNext()) {
//            Student student = iterator.next();
//            System.out.println(student + "\t" + avg(student));
//        }


        for (Student student : students) {
            System.out.println("" + student + "\t 平均成绩:" + avg(student));
        }
    }

    // 计算总成绩
    public static int sum(Student student) {
        return student.getTotal();
    }

    // 计算平均分
    public static double avg(Student student) {
        return (student.getTotal() / 2.0);
    }
}
2.4.2 Stack 类动态存储数据

Stack 类代表后进先出(LIFO) 堆栈的对象, Stack 继承自 Vector 所以它有所有 Vector 中的方法。

 public class Stack<E> extends Vector<E>

Stack 常用方法:

方法名返回值类型描述
empty()boolean判断此堆栈是否为空
peek()E返回此堆栈顶部的对象,而不从堆栈中删除它
pop()E返回并删除此堆栈顶部的对象
push(E item)E将指定对象添加到堆栈的顶部
search(Object o)int返回对象在此堆栈上的从1开始的位置,如果对象不在堆栈中,则返回 -1

示例

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        // 向Stack添加元素
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        // Stack 弹出元素
        System.out.println(stack.pop());  // 4
        // Stack 查看但不弹出
        System.out.println(stack.peek());  // 3
        // 判断是否为空
        System.out.println(stack.isEmpty());  // false
        // 查找元素所在位置
        System.out.println(3);  // 3
        System.out.println(stack);  // [1, 2, 3]
    }
}
2.4.3 ArrayList 类动态存储数据

ArrayList 是 Java 编程语言中的一个类,位于 java.util 包中。它是一个动态数组,可以根据需要自动调整大小。ArrayList 通过插入和删除元素来维护内部数组的大小,并提供了许多有用的方法来操作列表数据。可以存 null

以下是ArrayList的一些主要特点和常用方法:

  1. 动态大小:ArrayList可以根据需要动态增加或减少其大小,无需手动管理数组的大小。

  2. 允许重复元素:ArrayList可以包含重复的元素。

  3. 随机访问:可以使用索引访问ArrayList中的元素,通过get(index)方法获取指定位置的元素。

  4. 增删操作:可以使用add(element)方法在列表末尾添加元素,使用remove(index)方法删除指定位置的元素。

  5. 数组转换:可以使用toArray()方法将ArrayList转换为数组,或者使用Arrays.asList(array)方法将数组转换为ArrayList。

示例

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("小羊呆呆");
        list.add("犯困桃子");
        list.add("中科盛康人才");
        list.add("桃子");
        list.add("张三");
        list.add("盛康人才");

        /**
         * 错误删除元素,删除除倒数第二个元素外都会报错'ConcurrentModificationException(并发修改异常)'
         */
        //for (String str : list) {
        //    if ("张三".equals(str)) {
        //        list.remove(str);
        //    }
        //}
        System.out.println(list);  // [小羊呆呆, 犯困桃子, 中科盛康人才, 桃子, 盛康人才]

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String s = iterator.next();
            if ("桃子".equals(s)) {
                // 利用iterator方法删除元素,如果使用list.remove会报错
                iterator.remove();
                continue;
            }
            System.out.println(s);
        }
        // 判断是否包含某个元素
        System.out.println(list.contains("小羊呆呆"));  // true
        // 寻找对应元素下标
        System.out.println(list.indexOf("犯困桃子"));  // 1
        // 输出所有元素
        System.out.println(list);  // [小羊呆呆, 犯困桃子, 中科盛康人才, 盛康人才]

        // subList()返回的是原始列表的一个视图(view),而不是一个新的独立列表。
        // 这意味着对返回的子列表进行的任何修改都会反映在原始列表中,并且对原始列表的修改也会影响到子列表。
        List<String> strings = list.subList(1, 3);
        System.out.println(strings);  // [犯困桃子, 中科盛康人才]
        strings.set(0, "桃子姐姐");
        System.out.println(list);  // [小羊呆呆, 桃子姐姐, 中科盛康人才, 盛康人才]
        System.out.println(strings.contains("小羊呆呆"));  // false
        strings.clear();
        System.out.println(list.size());  // 2
    }
}

ArrayList 是非线程安全的,默认容量为10,默认每次扩容为1.5倍。

构造方法
ArrayList类提供了多种构造方法来创建ArrayList对象。以下是一些常用的构造方法:

  1. ArrayList():创建一个空的ArrayList对象,默认初始容量为10。
ArrayList<String> list = new ArrayList<>();
  1. ArrayList(int initialCapacity):创建一个具有指定初始容量的ArrayList对象。
ArrayList<String> list = new ArrayList<>(20);
  1. ArrayList(Collection<? extends E> c):创建一个包含指定集合中的元素的ArrayList对象。
List<String> collection = Arrays.asList("Apple", "Banana", "Orange");
ArrayList<String> list = new ArrayList<>(collection);
  1. ArrayList<E>(ArrayList<? extends E> c):创建一个包含指定ArrayList中的元素的ArrayList对象。
ArrayList<String> originalList = new ArrayList<>();
originalList.add("Apple");
originalList.add("Banana");
originalList.add("Orange");

ArrayList<String> newList = new ArrayList<>(originalList);

这些构造方法允许你根据不同的需求来创建ArrayList对象。你可以选择根据默认大小创建一个空列表,指定初始容量,或者使用现有的集合来初始化列表。

需要注意的是,尖括号中的类型参数E表示ArrayList中元素的类型。在实际使用时,根据需要替换为实际的类型。

2.4.4 LinkedList 类动态存储数据

LinkedList 类是 Java 集合框架中的一个双向链表实现,它实现了 List 接口。与 ArrayList 相比,LinkedList 在插入和删除元素时具有更好的性能,但在访问和搜索元素时较差。

LinkedList 支持实现所有 List 接口可选列表的操作,并允许元素值是任何数据,包括 null

构造方法
LinkedList类提供了以下几个构造方法:

  1. LinkedList():创建一个空的LinkedList对象。
// 创建一个空的LinkedList对象
LinkedList<String> emptyList = new LinkedList<>();
System.out.println("Empty List: " + emptyList); // 输出:Empty List: []
  1. LinkedList(Collection<? extends E> c):创建一个包含指定集合中的元素的LinkedList对象,元素按照集合的迭代器返回顺序添加到列表的末尾。
// 创建一个包含指定集合中的元素的LinkedList对象
LinkedList<Integer> numbers = new LinkedList<>(List.of(1, 2, 3, 4, 5));
System.out.println("Numbers: " + numbers); // 输出:Numbers: [1, 2, 3, 4, 5]

示例

import java.util.Arrays;
import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        // 创建一个空的LinkedList对象
        LinkedList<String> linkedList = new LinkedList<>();

        // 添加元素
        linkedList.add("apple");
        linkedList.addFirst("banana");
        linkedList.addLast("orange");
        System.out.println("LinkedList: " + linkedList); // 输出:LinkedList: [banana, apple, orange]

        // 转换成数组
        Object[] array = linkedList.toArray();
        System.out.println("Array: " + Arrays.toString(array)); // 输出:Array: [banana, apple, orange]

        // 获取元素
        String firstElement = linkedList.getFirst();
        String lastElement = linkedList.getLast();
        String secondElement = linkedList.get(1);
        System.out.println("First element: " + firstElement); // 输出:First element: banana
        System.out.println("Last element: " + lastElement); // 输出:Last element: orange
        System.out.println("Second element: " + secondElement); // 输出:Second element: apple

        // 判断是否包含元素
        boolean containsApple = linkedList.contains("apple");
        boolean containsGrape = linkedList.contains("grape");
        System.out.println("Contains apple: " + containsApple); // 输出:Contains apple: true
        System.out.println("Contains grape: " + containsGrape); // 输出:Contains grape: false

        // 删除元素
        linkedList.removeFirst();
        linkedList.removeLast();
        linkedList.remove("apple");
        System.out.println("LinkedList after removal: " + linkedList); // 输出:LinkedList after removal: []

        // 判断是否为空
        boolean isEmpty = linkedList.isEmpty();
        System.out.println("Is empty: " + isEmpty); // 输出:Is empty: true

        // 获取列表的大小
        int size = linkedList.size();
        System.out.println("Size of LinkedList: " + size); // 输出:Size of LinkedList: 0
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值