Java[7] 集合框架

教材

《Java核心技术·卷I 开发基础(原书第12版)》

《Java语言程序设计(第3版)》


一、集合接口

1.1 Java 集合框架

  • Java 集合框架将接口与实现分离
  • 一旦构造了集合对象 就不需要知道究竟使用了哪种实现
  • 一般在构造集合对象时才会使用具体的类 通常会使用接口类型引用集合对象

1.2 Collection 接口

1.2.1 基本操作

boolean add(E element):将一个元素element添加到集合中。如果改变了集合则返回ture。

boolean remove(Object obj):将一个等于obj的对象从集合中删除。如果改变了集合则返回true。

boolean contains(Object obj):如果集合中包含于obj相等的对象则返回true。

boolean isEmpty():如果集合中没有元素则返回true。

int size():返回当前集合中包含元素的个数。

Iterator iterator():返回一个迭代器。

default void forEach(Consumer<? super T> action):对集合中的每个元素执行指定的操作。

1.2.2 批量操作

boolean addAll(Collection<? extends E> other):将other集合中的所有元素添加到当前集合中。

boolean removeAll(Collection<?> other):将other集合中的所有元素从当前集合中删除。

default boolean removeIf(Predicate<? super E> filter):将当前集合中时使filter返回true的元素删除

boolean containsAll(Collection<?> other):如果当前集合中包含other集合中的所有元素则返回true

boolean retainAll(Collection<?> other):只保留当前集合和other集合都含有的元素。

void clear():清除当前集合所有元素。

1.2.3 数组操作

Object[] toArray():返回包含当前集合中所有元素的数组。

<T> T[] toArray(IntFunction<T[]> generator):返回包含当前集合中所有元素的数组,返回数组的元素类型是指定的数组类型。

1.3 Map 接口

映射(Map)用来存放键值对。

1.3.1 基本操作

public V put(K key, V value):向映射对象中添加一个键值对。如果这个键已经存在,新对象将取代之前与这个键关联的对象。这个方法返回键对应的旧值。如果之前没有这个键,则返回null。

public V get(Object key):返回指定键对应的值。如果没有找到指定键,则返回null。

default V getOrDefault(Object key, V defaultValue):返回指定键对应的值。如果没有找到指定键,则返回defaultValue。

public V remove(Object key):从映射中删除指定键的键值对。

public boolean containsKey(Object key):如果映射中含有这个键,则返回true。

public boolean containsValue(Object value):如果映射中含有这个值,则返回true。

public int size():返回映射中包含的键值对个数。

public boolean isEmpty():返回映射是否为空。

default void forEach(BiConsumer<? super K, ? super V> action):对映射中的所有键值对应用这个动作。

default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction):如果key与一个非null值v关联,将函数应用到v和value,将key与函数结果关联。

default V getOrDefault(Object key, V defaultValue):返回指定键对应的值,如果没有值则返回默认值。

default putIfAbsent(K key, V value):如果指定键不存在或者与null关联,则将它与value关联。=,并返回null。否则返回关联的值。

Set<K> keySet():返回键集。

Collection<V> values():返回值集。

Set<Map.Entry<K,V>> entrySet():返回键值对集。

1.3.2 批量操作

public void putAll(Map<? extends K, ? extends V> entries):将指定映射中的所有键值对添加到当前映射中。

public void clear():删除映射中所有键值对。

public Set<K> keySet():返回由键组成的Set对象。

public Collection<V> values():返回由值组成的Collection对象。

public Set<Map.Entry<K, V>> entrySet():返回包含Map.Entry<K, V>的一个Set对象。

1.4 Iterator(迭代器) 接口

Collection<String> c = ...;
Iterator<String> iter = c.iterator();
while (iter.hasNext()) {
    String element = iter.next();
    ...    // do something with element
}
  • 4个方法:
  1. boolean hasNext():如果存在另一个可返回的元素,则返回true。
  2. E next():返回要访问的下一个对象。如果到末尾,则抛出NoSuchElementException异常。
  3. void remove():删除上次访问的对象。这个方法必须紧跟在访问一个元素之后。如果访问上一个元素之后集合已经发生了变化,这个方法将抛出一个IllegalStateException异常。
  4. default void forEachRemaining(Consumer<? super E> action):访问元素并传递到指定的动作,直到访问完所有元素或动作抛出异常。
  • Java 迭代器基本原理:

  1. 查找操作与位置变化紧密耦合(在执行查找操作的同时 迭代器的位置会随之向前移动)
  2. 可以认为 迭代器 位于两个元素之间

在调用 next 方法之前需要调用 hasNext 方法

在调用 remove 方法之前需要调用 next 方法(删除 next 方法返回的元素)否则不合法

补充

List是一个有序集合。可以使用两种方法访问元素:使用迭代器访问;使用整数索引访问。后者称为随机访问,可以按任意顺序访问元素。

List接口的部分方法(随机访问方法):

void add(int index, E element)

void remove(int index)

E get(int index)

E set(int index, E element)

ListIterator接口定义了一个方法用于在迭代器位置前面增加一个元素

void add(E element)

由数组支持的有序集合可以快速的随机访问,因此适合使用List方法并提供一个整数索引访问。链表尽管是有序的,但是随机访问很慢,所以最好使用迭代器访问。

二、集合类

2.1 链表(LinkedList)

链表将每个对象存放在单独的链接中。每个链接还存放着序列中下一个链接的引用。

在 Java 中,所有链表都是双向链接的,即每个链接还存放着序列中上一个链接的引用。

从链表中间删除一个元素很容易(常量时间),只需要更新所删除元素周围的链接即可。

LinkedList():构造一个空链表。

LinkedList(Collection<? extends E> c):构造一个链表,将集合c中的所有元素添加到链表中。

boolean add(E element):将元素element添加到链表末尾。

void add(int Index, E element):将元素element插入到链表索引为Index的位置。

boolean addAll(Collection<? extends E> c):将集合c中的所有元素添加到链表末尾。

boolean addAll(int Index, Collection<? extends E> c:将集合c中的所有元素从索引为Index的位置插入链表。

void addFirst(E element):将元素element添加到链表开头。

void addLast(E element):将元素element添加到链表末尾。
E get(int Index):返回链表中指定位置的元素。

E getFirst():返回链表中的第一个元素。

E getLast():返回链表中的最后一个元素。

E remove(int Index):将链表中指定位置的元素删除并返回。

E removeFirst():将链表中的第一个元素删除并返回。

E removeLast():将链表中的最后一个元素删除并返回。

2.2 散列集(HashSet)

散列表可以用于快速查找元素。每个元素有一个(整数)散列码。

HashSet():构造一个空散列集。

HashSet(Collection<? extends E> c):构造一个散列集,并将集合c中的所有元素添加到散列集中。

HashSet(int initialCapacity):构造一个空散列集,并指定散列集的初始容量。

HashSet(int initialCapacity, float loadFactor):构造一个空散列集,并指定散列集的初始容量和装填因子。

2.3 树集(TreeSet)

树集是一个有序集合。能够以任意顺序将元素插入集合中。在对集合进行遍历时,值将自动地按照排序后的顺序出现。

将一个元素添加到树中比添加到散列表中慢。

与检查数组或链表中的重复元素相比,使用树会快得多。

TreeSet():构造一个空树集。

TreeSet(Collection<? extends E> c):构造一个树集,其中包含集合c中的所有元素。

TreeSet(Comparator<? super E> comparator):构造一个空树集,根据给定的比较器排序。

TreeSet(SortedSet<E> s):构造一个树集,其中包含有序集s中的所有元素,根据有序集s的比较器排序。

Comparator<? super E> comparator():返回用于对元素进行排序的比较器。如果元素用Comparable接口的compareTo方法进行比较则返回Null。

E first():返回树集中的最小元素。

E last():返回树集中的最大元素。

E higher(E e):返回大于等于元素e的最小元素。如果没有则返回Null。
E lower(E e):返回小于等于元素e的最大元素。如果没有则返回Null。

E pollFirst():删除并返回树集中的最小元素。树集为空时返回Null。

E pollLast():删除并返回树集中的最大元素。树集为空时返回Null。

Iterator<E> descendingIterator():返回一个按照降序遍历树集中元素的迭代器。

2.4 数组双端队列(ArrayDeque)

Deque(双端队列)在队头和队尾都能高效地添加和删除元素。不支持在队列中间添加元素。

ArrayDeque():构造一个空数组双端队列。

ArrayDeque(Collection<? extends E> c):构造一个数组双端队列,其中包含集合c中的所有元素。

ArrayDeque(int numElements):构造一个空数组双端队列,指定初始容量。

boolean add(E e):在队尾添加元素,如果队列已满抛出一个IllegalStateException异常。

boolean offer(E e):在队尾添加元素,如果队列已满则返回false。

void addFirst(E e):在队头添加元素,如果队列已满抛出一个IllegalStateException异常。

void addLast(E e):在队尾添加元素,如果队列已满抛出一个IllegalStateException异常。

boolean offerFirst(E e):在队头添加元素,如果队列已满则返回false。

boolean offerLast(E e):在队尾添加元素,如果队列已满则返回false。

E remove():删除并返回队头元素,如果队列为空抛出一个NosuchElementException异常。

E poll():删除并返回队头元素,如果队列为空则返回Null。

E removeFirst():删除并返回队头元素,如果队列为空抛出一个NosuchElementException异常。

E removeLast():删除并返回队尾元素,如果队列为空抛出一个NosuchElementException异常。
E pollFirst():删除并返回队头元素,如果队列为空则返回Null。

E pollLast():删除并返回队尾元素,如果队列为空则返回Null。

E element():返回队头元素,如果队列为空抛出一个NosuchElementException异常。

E peek():返回队头元素,如果队列为空则返回Null。

E getFirst():返回队头元素,如果队列为空抛出一个NosuchElementException异常。

E getLast():返回队尾元素,如果队列为空抛出一个NosuchElementException异常。

E peekFirst():返回队头元素,如果队列为空则返回Null。

E peekLast():返回队尾元素,如果队列为空则返回Null。

2.5 优先队列(PriorityQueue)

PriorityQueue():

PriorityQueue(int initialCapacity):

PriorityQueue(Collection<? extends E> c):

PriorityQueue(Comparator<? super E> comparator):

PriorityQueue(int initialCapacity, Comparator<? ssuper E> comparator):

2.6 散列映射(HashMap)

HashMap():

HashMap(int initialCapacity):

HashMap(int initialCapacity, float loadFactor):

HashMap(Map<? extends K, ? extends V> m):

2.7 树映射(TreeMap)

TreeMap():
TreeMap(Comparator<? super K> comparator):

TreeMap(Map<? extends K, ? extends V> m):
TreeMap(SortedMap<? extends K, ? extends V> m):

2.8* 链接散列集(LinkedHashSet)

2.9* 链接散列映射(LinkedHashMap)

2.10* 枚举集(EnumSet)

2.11* 枚举映射(EnumMap)

三、副本与视图

通过使用视图,可以得到其他实现了Collection接口或Map接口的对象。

使用of静态方法生成Collection对象是不可修改的(传递到构造器即可修改)。

3.1 副本

使用集合类型的copyOf方法建立一个集合的不可修改副本。

3.2 视图

子范围视图

检查型视图

四、遗留集合

4.1 散列表(HashTable)

4.2 枚举(Enumeration)接口

4.3 属性映射(Properties)

4.4 栈(Stack)

4.5 位集(BitSet)


编程练习

import java.util.*;

public class StringUppercaseConversion {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>(Arrays.asList("apple", "banana", "orange"));
        strings.forEach(System.out::println);

//        // 通过索引遍历访问修改
//        for (int i = 0; i < strings.size(); i++) {
//            String string = strings.get(i);
//            strings.set(i, string.toUpperCase());
//        }
//        strings.forEach(System.out::println);

//        // 通过迭代器访问修改
//        ListIterator<String> iterator = strings.listIterator();
//        while (iterator.hasNext()) {
//            String string = iterator.next();
//            iterator.set(string.toUpperCase());
//        }
//        strings.forEach(System.out::println);

        // 调用replaceAll()方法修改
        strings.replaceAll(String::toUpperCase);
        strings.forEach(System.out::println);
    }
}

import java.util.*;
import java.util.regex.*;

public class ParseStringWords {
    public static void main(String[] args) {
        String text = "hello world\nhello java\nhello hadoop";
        List<String> allWords = new ArrayList<>();
        Set<String> uniqueWords = new HashSet<>();
        Set<String> duplicateWords = new HashSet<>();

        Pattern pattern = Pattern.compile("\\b[a-zA-Z'-]+\\b");
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            String word = matcher.group().toLowerCase();
            if (!uniqueWords.add(word)) {
                duplicateWords.add(word);
            }
            allWords.add(word);
        }

        System.out.println("The original words list: " + allWords);
        System.out.println("The duplicate words list: " + duplicateWords);
        System.out.println("The number of unique words is " + uniqueWords.size());
        System.out.println("The words list after eliminating duplicate words: " + uniqueWords);
    }
}

import java.util.*;

public class RandomIntegerSet {
    public static int getRandomInteger() {
        return (int) (Math.random() * (99 - 10) + 10);
    }

    public static void main(String[] args) {
        Set<Integer> hashSet = new HashSet<>();
        Set<Integer> treeSet = new TreeSet<>();

        for (int i = 0; i < 10; i++) {
            hashSet.add(getRandomInteger());
            treeSet.add(getRandomInteger());
        }

        System.out.println("The HashSet of 10 random integers: " + hashSet);
        System.out.println("The TreeSet of 10 random integers: " + treeSet);
    }
}

import java.util.*;

public class Employee implements Comparable<Employee> {
    private int id;

    public Employee() {
        this(0);
    }

    public Employee(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int compareTo(Employee other) {
        return Integer.compare(this.id, other.getId());
    }

    public String toString() {
        return "Employee" + id;
    }

    public static void main(String[] args) {
        Employee[] employees = new Employee[10];
        Random random = new Random();

        for (int i = 0; i < employees.length; i++) {
            employees[i] = new Employee(random.nextInt(100));
        }

        Set<Employee> employeeSet = new TreeSet<>(Arrays.asList(employees));
        System.out.println(employeeSet);
    }
}

import java.util.*;

public class PriorityQueueTest {
    public static void main(String[] args) {
        Integer[] array = {1, 5, 3, 7, 6, 9, 8};
        Queue<Integer> queue = new PriorityQueue<>(Arrays.asList(array));
        System.out.print(queue);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值