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基础知识 第九章 集合的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)