本文主要是介绍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基础知识 第九章 集合的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!