java核心技术卷1基础知识 第九章 集合

2021/4/19 12:55:14

本文主要是介绍java核心技术卷1基础知识 第九章 集合,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

# 第九章 集合 ## 9.1 Java集合框架 ### 9.1.1 集合接口与实现分离 队列接口最简单实现 ``` public interface Queue<E> {     void add(E element);     E remove();     int size(); } ``` 队列有两种实现方式,一种是循环数组,另一种是链表 ``` public class CircularArrayQueue<E> implements Queue<E>{     private int head;     private int tail;     CircularArrayQueue(int capacity){}     public void add(E element){}     public E remove(){};     public int size(){};     private E[] elements; } ``` ### 9.1.2 Collection 接口 ``` public interface Collection<E> {     boolean add(E element);     Iterator<E> iterator; } ``` 集合中不允许有重复对象 所以若添加对象已存在则add方法返回false ### 9.1.3 迭代器 ``` public interface Iterator<E> {     E next();     boolean hasNext();//调用next()前使用hasnext检查是否有下一个     void remove();     default void forEachRemaining(Consumer<? super E> ction); } ``` 也可以使用foreach进行循环 编译器自动转换为带有迭代器的循环 ``` for(String element:c) {     //do something with element; } ``` Java迭代器位于两个元素之间,当调用next时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。 Iterator接口的remove方法将会删除上次调用next方法时返回的元素。调用remove之前没有调用next将是不合法的,会抛出异常。 ### 9.1.4 泛型实用方法 Java类库提供了一个类AbstractCollection,它保持基础方法size和iterator仍为抽象方法。 具体集合类可以扩展AbstractCollection类。由具体集合类提供iterator方法,contain方法由AbstractCollection超类提供 ## 9.2 集合框架中的接口 集合有两个基本接口:Collection和Map 使用boolean add(E element) 映射使用V put(K key,V value)添加键值对 迭代器必须顺序访问元素 Set接口等同于Collection接口,Set的add方法不允许添加重复元素,两个集包含相同元素即相同,不在乎顺序。 ## 9.3 具体集合 ### 9.3.1 链表 链表基于普通数组删除和插入元素开销大的原因(移动元素) 在Java中,链表都是双向链表 ``` var staff=new LinkedList<String>(); staff.add("Amy"); staff.add("Bob"); staff.add("Carl"); Iterator<String> iter=staff.iterator(); String first=iter.next(); String second=iter.next(); iter.remove(); ``` ListIterator提供了反向遍历链表的方法 ``` E previous(); boolean hasPrevious() ``` 与next方法一样,previous返回越过的对象 不能使用同时具有读写功能的两个迭代器 LinkedList提供访问某个特定元素的get方法,效率不高(每次从头开始) 可以使用System.out.println(a)//打印链表a所有元素 ### LinkedList.java ``` package javaSX.linkedList;
import java.util.*;
public class LinkedListTest {     public static void main(String[] args) {         var a = new LinkedList<String>();         a.add("Amy");         a.add("Bob");         a.add("Carl");
        var b = new LinkedList<String>();         b.add("Daivd");         b.add("Ethan");         b.add("Frank");         b.add("Gaussian");
        ListIterator<String> aIter = a.listIterator();         Iterator<String> bIter = b.iterator();
        while (bIter.hasNext()) {// merge from b to a             if (aIter.hasNext())                 aIter.next();             aIter.add(bIter.next());         }         System.out.println(a);         bIter = b.iterator();         while (bIter.hasNext()) {             bIter.next();             if (bIter.hasNext()) {                 bIter.next();                 bIter.remove();// remove every second word in b             }         }         System.out.println(b);         a.removeAll(b);         // remove all words in b from a         // 从a中删除b中的所有单词         System.out.println(a);     } } ``` ### 9.3.3 散列集 不在意元素存储顺序,快速查找元素,这就是散列表,散列表为每一个对象计算一个整数(散列码)。散列表用链表数组实现 ### SetTest.java ``` package javaSX.set;
import java.util.*;
public class SetTest {// print all unique words in System.in     public static void main(String[] args) {         var words = new HashSet<String>();         long totalTime = 0;         try (var in = new Scanner(System.in)) {             while (in.hasNext()) {                 String word = in.next();                 long callTime = System.currentTimeMillis();                 words.add(word);                 callTime = System.currentTimeMillis() - callTime;                 totalTime += callTime;             }         }         Iterator<String> iter = words.iterator();         for (int i = 1; i <= 20 && iter.hasNext(); i++) {             System.out.println(iter.next());         }         System.out.println("...");         System.out.println(words.size() + "distinct words" + totalTime + "mill seconds");     } } ``` ### 9.3.4 树集 树集是一个有序集合,使用红黑树完成。 将一个元素添加到树中比添加到散列表中慢,但是与检查数组或链表中的重复元素相比,使用树会快很多。使用树集的元素必须实现Comparable接口。
下面的程序创建了Item对象的两个树集,第一个按照部件编号排序,第二个使用一个定制的比较器按照描述信息排序。 ### TreeSetTest.java ``` package javaSX.treeSet;
import java.util.*;
public class TreeSetTest {     public static void main(String[] args) {         var parts = new TreeSet<Item>();         parts.add(new Item("Toaster", 24));         parts.add(new Item("widget", 13));         parts.add(new Item("modem", 2411));         System.out.println(parts);// 默认按照部件编号排序         var sortByDescription = new TreeSet<Item>(Comparator.comparing(Item::getDescription));// 按照描述信息排序
        sortByDescription.addAll(parts);         System.out.println(sortByDescription);     } } ``` ### Item.java ``` package javaSX.treeSet;
import java.util.Objects;
public class Item implements Comparable<Item> {     private String description;     private int partNumber;
    public Item(String aDescription, int aPartNumber) {         description = aDescription;         partNumber = aPartNumber;     }
    public String getDescription() {         return description;     }
    public String toString() {         return "[description=" + description + ",partNumber=" + partNumber + "]";     }
    public boolean equals(Object otherObject) {         if (this == otherObject)             return true;         if (otherObject == null)             return false;         if (getClass() != otherObject.getClass())             return false;         var other = (Item) otherObject;         return Objects.equals(description, other.description) && partNumber == other.partNumber;     }
    public int hashCode() {         return Objects.hash(description, partNumber);     }
    public int compareTo(Item other) {         int diff = Integer.compare(partNumber, other.partNumber);         return diff != 0 ? diff : description.compareTo(other.description);     } } ``` ### 9.3.5 队列与双端队列 Java6中引入了Deque接口,ArrayDeque和LinkedList类实现了这个接口,可以提供双端队列。 ### 9.3.6 优先队列 优先队列元素可以按任意顺序插入,但会按有序顺序检索。意味着调用remove,总会获得最小元素。优先队列使用堆来实现。 ### PriorityQueueTest.java ``` package javaSX.priorityQueue;
import java.util.*; import java.time.*;
public class PriorityQueueTest {     public static void main(String[] args) {         var pq = new PriorityQueue<LocalDate>();         pq.add(LocalDate.of(1906, 12, 9));         pq.add(LocalDate.of(1815, 1, 9));         pq.add(LocalDate.of(1920, 12, 19));         pq.add(LocalDate.of(1916, 2, 11));
        System.out.println("Iterating over elements....");         for (LocalDate date : pq) {             System.out.println(date);         }         System.out.println("Removeing elements...");         while (!pq.isEmpty())             System.out.println(pq.remove());     } } ``` ## 9.4 映射 存放键值对 ### 9.4.1 基本映射操作 ``` var staff=new HashMap<String,Employee>(); staff.put("123",new Employee("Amy")); staff.remove("123"); staff.forEach((k,v)->System.out.println("key="+k+",value="+v)); getorDefault()//有则取值,无则为默认值 ``` ### 9.4.3 映射视图 可以枚举一个映射的所有键 ``` Set<String> keys=map.keySet(); for(String key:keys) {     ... } ``` 使用以下代码查看键和值 ``` for(Map.Entry<String,Employee> entry:staff.entrySet()) {     String k=entry.getKey();     Employee v=entry.getValue();     ... } ``` 不能向键值视图添加元素 ### 9.4.4 弱散列映射 WeakHashMap使用弱引用保存键,WeakHashMap将删除不被引用条目 ### 9.4.5 链接散列表与映射 当你的方法返回true时,添加一个新映射条目就会导致删除eldest项,下面的缓存最多存放100个元素 ## 9.5 视图与包装器 ### 9.5.1 小集合 生成给定元素的集或列表,以及给定键/值对的对象。 ### 9.5.2 子范围 ``` List<Employee> group2=staff.subList(10,20);//第一个索引包含在内,第二个索引不包含在内。 SortedMap<K,V> subMap(K from,K to);//这些方法将返回大于等于from且小于to的所有元素构成的子集。 SortedMap<K,V> headMap(K to); SortedMap<K,V> tailMap(K from); ```

这篇关于java核心技术卷1基础知识 第九章 集合的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程