Java编程思想--17容器深入研究

17.1 完整的容器分类法

Java容器类库简图
上图虚线框表示接口,长虚线框表示abstract类。空心箭头表示一个特定的类实现了一个接口。实心箭头某个类可以生成箭头所指类的对象。

17.2 填充容器

  1. Collections.nCopies
List<StringAddress> list= new ArrayList<StringAddress>(
      Collections.nCopies(4, new StringAddress("Hello")));
  1. Collections.fill
list = Collections.fill(list, new new StringAddress("Hello"));

17.2.1 一种Generator解决方法

17.2.2 Map生成器

17.2.3 使用Abstract类

17.3 Collections的功能方法

  1. 添加
方法解释
boolean add(T)添加一个元素T,成功返回true
boolean addAll(Collection<? extends T>)添加参数中的所有参数
  1. 查询类
方法解释
int size()添加一个元素T,成功返回true 返回容器元素数目
boolean isEmpty()查询容器是否为空
boolean contains(T)查询容器是否包含某元素
boolean containsAll(Collection<? extends T>)查询是否包含容器内所有元素
  1. 删除类
方法解释
boolean remove(T)删除一个元素T,成功返回true
boolean removeAll(Collection<?>)删除参数中的所有参数
boolean retainAll(Collection<?>)删除不包含在参数中容器中的所有参数
void clear()移除所有元素
  1. 转换类
方法解释
Object[] toArray()返回一个数组,该数组包含容器中所有元素
<T> T[] removeAll(T[] a)返回一个数组,该数组包含容器中所有元素,返回结果与运行时相同,而不是相同的Object
boolean retainAll(Collection<?>)删除不包含在参数中容器中的所有参数

17.4 可选操作

执行不同的添加和移除方法在Collection接口中都是可选操作。这意味着实现类并不需要为这些方法提供定义功能。当调用未被实现的方法时会抛出UnsupportedOperation异常。这样做的目的是防止接口爆炸。

17.5 List功能方法

List有专用的listIterator。

  public static void iterMotion(List<String> a) {
    ListIterator<String> it = a.listIterator();
    b = it.hasNext();
    b = it.hasPrevious();
    s = it.next();
    i = it.nextIndex();
    s = it.previous();
    i = it.previousIndex();
  }

17.6 Set和存储顺序

Set(interface)Set内的元素是唯一的。加入Set的元素必须定义equals方法以确保对象的唯一性。Set不保证插入元素的顺序
HashSet为了快速查找而设计的Set,存入HashSet的元素必须定义hashCode()
TreeSet保持次序的Set。元素必须事先Comparable接口
LinkedHashSet具有HashSet的查询速度,且内部使用链表维护元素的顺序。元素也必须定义hashCode方法

17.6.1 SortedSet

Sorted提供了额外的操作:

  • Object first()
  • Object last()
  • SortedSet subSet(from, to)
  • SortedSet headSet(to)
  • SortedSet tailSet(from)

17.7 队列

17.1.1 优先级队列

PriorityQueue需要类实现Comparable接口

17.2.2 双向队列

双向队列,可以在忍一段添加或移除元素。LinkedList包含支持双向队列的方法。

17.8 理解Map

HashMapMap基于散列表的实现,可以通过构造器设置容量和负载因子,以调整容器的性能。
LinkedHashMapMap基于散列表的实现。 取键值对的顺序是插入顺序或者最近最少使用的次序(LRU)
TreeMap基于红黑树的实现。查看“键”或“键值对”时,他们会被排序。需要元素具有Comparable接口。
WeakHashMap弱键映射,允许释放所指对象。当映射之外不存在引用指向某个“键”,则此键可以被垃圾收集器回收。
ConcurrentHashMap一种线程安全的Map,它不涉及同步加锁
IdentityHashMap使用==代替equals()对“键”进行比较,为解决特殊问题而设计

17.9 散列与散列码

17.9.2 为速度而散列

数组并不保存键本身,而是通过键生成一个数字,将其作为数组的下标。这个数字就是散列码。Object中有hashCode方法,可被覆盖。

由于散列的槽位(slot)通常被称为桶位(bucket)。为了使散列分布均匀,通道的数量通常是质数。

但对现代处理起来说,除法和求余是最慢的操作。使用2的整数次方长度的散列表,可用掩码代替除法。

17.9.3 覆盖hashCode

17.10 选择接口的不同实现

  1. List的选择
  2. Set:HashSet最好用,LinkedHashSet保持了元素的插入顺序;TreeSet保持了元素的顺序。

17.11 实用方法

java.utils.Collections类内部有大量用于容器的实用方法。

方法简介
min(Collection)/max(Collection)返回集合内的最大/小元素
min(Collection, Comparator)/max(Collection, Comparator)根据比较器返回最大/最小元素
indexOfSubList(List source, List target)返回target在source中第一次出现的位置,失败返回-1
lastIndexOfSubList(List source, List target)返回target在source中最后一次出现的位置,失败返回-1
replaceALL(List<T>, T oldVal, T newVal)替换
reverse(List)逆转所有元素的顺序
rotate(List, int distance)全体元素后移distance个位置,将末尾的元素循环到前面来
Shuffle(List), Shuffle(List, Random)随机打乱列表顺序
sort(List<T>/sort(List<T>, Comparator<? Super T>)自然排序
copy(List<? super T> dest, List<? super T> src)将src中的元素复制到dest中
swap(List, int i, int j)交换元素位置,比自己写的代码快
fill(List<? super T>, T x)用对象x替换list中所有元素
nCopies(int n, T x)返回大小为n的List<T>,此List不可改变,其中的引用都指向x
frequency(Collection, T x)返回Collection中元素x的个数

17.12 持有对象

java.lang.ref中有三个继承自Reference的类:SoftReference、WeakReference和PhantomReference。该三个类别为垃圾回收器提供了不同级别的指示,排列顺序由弱到强。

import java.lang.ref.*;
import java.util.*;

class VeryBig {
  private static final int SIZE = 10000;
  private long[] la = new long[SIZE];
  private String ident;
  public VeryBig(String id) { ident = id; }
  public String toString() { return ident; }
  protected void finalize() {
    System.out.println("Finalizing " + ident);
  }
}

public class References {
  private static ReferenceQueue<VeryBig> rq =
    new ReferenceQueue<VeryBig>();
  public static void checkQueue() {
    Reference<? extends VeryBig> inq = rq.poll();
    if(inq != null)
      System.out.println("In queue: " + inq.get());
  }
  public static void main(String[] args) {
    int size = 10;
    // Or, choose size via the command line:
    if(args.length > 0)
      size = new Integer(args[0]);
    LinkedList<SoftReference<VeryBig>> sa =
      new LinkedList<SoftReference<VeryBig>>();
    for(int i = 0; i < size; i++) {
      sa.add(new SoftReference<VeryBig>(
        new VeryBig("Soft " + i), rq));
      System.out.println("Just created: " + sa.getLast());
      checkQueue();
    }
    LinkedList<WeakReference<VeryBig>> wa =
      new LinkedList<WeakReference<VeryBig>>();
    for(int i = 0; i < size; i++) {
      wa.add(new WeakReference<VeryBig>(
        new VeryBig("Weak " + i), rq));
      System.out.println("Just created: " + wa.getLast());
      checkQueue();
    }
    SoftReference<VeryBig> s =
      new SoftReference<VeryBig>(new VeryBig("Soft"));
    WeakReference<VeryBig> w =
      new WeakReference<VeryBig>(new VeryBig("Weak"));
    System.gc();
    LinkedList<PhantomReference<VeryBig>> pa =
      new LinkedList<PhantomReference<VeryBig>>();
    for(int i = 0; i < size; i++) {
      pa.add(new PhantomReference<VeryBig>(
        new VeryBig("Phantom " + i), rq));
      System.out.println("Just created: " + pa.getLast());
      checkQueue();
    }
  }
} /* 
Just created: java.lang.ref.SoftReference@2ff4acd0
Just created: java.lang.ref.SoftReference@54bedef2
Just created: java.lang.ref.SoftReference@5caf905d
Just created: java.lang.ref.SoftReference@27716f4
Just created: java.lang.ref.SoftReference@8efb846
Just created: java.lang.ref.SoftReference@2a84aee7
Just created: java.lang.ref.SoftReference@a09ee92
Just created: java.lang.ref.SoftReference@30f39991
Just created: java.lang.ref.SoftReference@452b3a41
Just created: java.lang.ref.SoftReference@4a574795
Just created: java.lang.ref.WeakReference@f6f4d33
Just created: java.lang.ref.WeakReference@23fc625e
Just created: java.lang.ref.WeakReference@3f99bd52
Just created: java.lang.ref.WeakReference@4f023edb
Just created: java.lang.ref.WeakReference@3a71f4dd
Just created: java.lang.ref.WeakReference@7adf9f5f
Just created: java.lang.ref.WeakReference@85ede7b
Just created: java.lang.ref.WeakReference@5674cd4d
Just created: java.lang.ref.WeakReference@63961c42
Just created: java.lang.ref.WeakReference@65b54208
Finalizing Weak 3
Just created: java.lang.ref.PhantomReference@1be6f5c3
Finalizing Weak 2
In queue: null
Finalizing Weak 1
Just created: java.lang.ref.PhantomReference@6b884d57
Finalizing Weak 0
In queue: null
Finalizing Weak
Just created: java.lang.ref.PhantomReference@38af3868
Finalizing Weak 9
In queue: null
Finalizing Weak 8
Finalizing Weak 7
Just created: java.lang.ref.PhantomReference@77459877
Finalizing Weak 6
Finalizing Weak 5
Finalizing Weak 4
In queue: null
Just created: java.lang.ref.PhantomReference@5b2133b1
In queue: null
Just created: java.lang.ref.PhantomReference@72ea2f77
In queue: null
Just created: java.lang.ref.PhantomReference@33c7353a
In queue: null
Just created: java.lang.ref.PhantomReference@681a9515
In queue: null
Just created: java.lang.ref.PhantomReference@3af49f1c
In queue: null
Just created: java.lang.ref.PhantomReference@19469ea2
In queue: null
*///:~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值