您的位置:首页 > 编程语言 > Java开发

Thinking in Java 第17章 容器深入研究(17.10-17.14)

2016-07-22 08:58 821 查看
//声明:部分内容引自《Java编程思想(第四版)》机械工业出版社

【连接接口的不同实现】

– Hashtable、Vector、Stack 的“特征”是,它们是过去遗留下来的类,目的只是为了支持老的程序,所以最好不要再新的程序中使用。

– 容器之间的区别通常是:所使用的接口是由什么样的数据结构实现的。

例:ArrayList 和 LinkedList都实现了 List 接口,但 ArrayList 底层由数组支持,而 LinkedList 由双向链表实现。所以,如果要经常在表中插入或删除元素,LinkedList 比较合适,否则,应使用速度更快的 ArrayList。

例:Set 被可实现为 TreeSet、HashSet 或 LinkedSet。HashSet 最常用,查询速度最快;LinkedHashSet 保持元素插入的次序;TreeSet 基于 TreeMap,生成一个总是处于排序状态的 Set。

【实用方法】

package containers;//: containers/Utilities.java
// Simple demonstrations of the Collection utilities.

import java.util.*;

import static net.mindview.util.Print.print;

/**
* Created by JT on 2016/7/22.
*/
public class Utilities {
static List<String> list = Arrays.asList("one Two three Four five six one".split(" "));

public static void main(String[] args) {
print(list);
print("'list' disjoint (Four)?: " + Collections.disjoint(list, Collections.singletonList("Four"))); // disjoint(Collection, Collection): 当两个集合没有任何相同元素时,返回 true.
print("max: " + Collections.max(list)); // max(Collection)/min(Collection): 返回参数 Collection 中最大或最小的元素,采用 Collection 内置的自然比较法,对大小写敏感.
print("min: " + Collections.min(list));
print("max w/ comparator: " + Collections.max(list, String.CASE_INSENSITIVE_ORDER)); // max(Collection, Comparator)/min(Collection, Comparator): 返回参数 Collection 中最大或最小的元素,采用 Comparator 进行比较,对大小写不敏感.
print("min w/ comparator: " + Collections.min(list, String.CASE_INSENSITIVE_ORDER));
List<String> sublist = Arrays.asList("Four five six".split(" "));
print("indexOfSubList: " + Collections.indexOfSubList(list, sublist)); // indexOfSubList(List source, List target): 返回 target 在 source 中第一次出现的位置,或者在找不到时返回 -1.
print("lastIndexOfSubList: " + Collections.lastIndexOfSubList(list, sublist)); // lastIndexOfSubList(List source, List target): 返回 target 在 source 中最后一次出现的位置,或者在找不到时返回 -1.
Collections.replaceAll(list, "one", "Yo"); // replaceAll(List<T>, T oldVal, T newVal): 使用 newVal 替换所有的 oldVal.
print("replaceAll: " + list);
Collections.reverse(list); // reverse(List): 逆转所有元素的次序.
print("reverse: " + list);
Collections.rotate(list, 3); // rotate(List, int distance): 所有元素向后移动 distance 个位置,将末尾的元素循环到前面来.
print("rotate: " + list);
List<String> source = Arrays.asList("in the matrix".split(" "));
Collections.copy(list, source); // copy(List<? super T> dest, List<? extends T> src): 将 src 中的元素复制到 dest.
print("copy: " + list);
Collections.swap(list, 0, list.size() - 1); // swap(List, int i, int j): 交换 List 中位置 i 与 位置 j 的元素。通常比你自己写的代码快.
print("swap: " + list);
Collections.shuffle(list, new Random(47)); // shuffle(List, Random)/shuffle(List): 随机改变指定列表的顺序。前者可以由程序员自己决定随机机制,后者使用 Collection 自带的随机机制.
print("shuffle: " + list);
Collections.fill(list, "pop"); // fill(List<? super T>, T x): 用对象 x 替换 List 中的所有元素.
print("fill: " + list);
print("frequency of 'pop': " + Collections.frequency(list, "pop")); // frequency(Collection, Object x): 返回 Collection 中等于 x 的元素个数.
List<String> dups = Collections.nCopies(3, "snap"); // nCopies(int n, T x): 返回大小为 n 的 List<T>,此 List 不可改变,其中的引用都指向 x.
print("dups: " + dups);
print("'list' disjoint 'dups'?: " + Collections.disjoint(list, dups));
// Getting an old-style Enumeration:
Enumeration<String> e = Collections.enumeration(dups); // enumeration(Collection<T>): 为参数生成一个旧式的 Enumeration<T>.
Vector<String> v = new Vector<String>();
while(e.hasMoreElements())
v.addElement(e.nextElement());
// Converting an old-style Vector to a List via an Enumeration:
ArrayList<String> arrayList = Collections.list(v.elements()); // list<Enumeration<T> e>: 产生一个 ArrayList<T>,它包含的元素顺序,与(旧式的)Enumeration(Iterator 的前身)返回这些元素的顺序相同。用来转换遗留的老代码。
print("arrayList:" + arrayList);
}
}


– List 的排序和查询。

package containers;//: c
c765
ontainers/ListSortSearch.java

import java.util.*;

import static net.mindview.util.Print.print;

/**
* Created by JT on 2016/7/22.
*/
public class ListSortSearch {
public static void main(String[] args) {
List<String> list = new ArrayList<String>(Utilities.list);
list.addAll(Utilities.list);
print(list);
Collections.shuffle(list, new Random(47)); // 打乱顺序.
print("shuffled: " + list);
// Use a ListIterator to trim off the last elements:
ListIterator<String> it = list.listIterator(10);
while (it.hasNext()) {
it.next();
it.remove();
}
print("Trimmed: " + list); // 修改后的 list, 保留前十个元素.
Collections.sort(list); // 排序(按字母,区分大小写)
print("Sorted: " + list);
String key = list.get(7);
int index = Collections.binarySearch(list, key);
print("Location of " + key + " is " + index + ", list.get(" + index + ") = " + list.get(index));
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
print("Case-insensitive sorted: " + list);
key = list.get(7);
index = Collections.binarySearch(list, key, String.CASE_INSENSITIVE_ORDER); // 排序(按字母,不区分大小写).
print("Location of " + key + " is " + index + ", list.get(" + index + ") = " + list.get(index));
}
}


– 设定 Collection 或 Map 为不可修改。

package containers;//: containers/ReadOnly.java
// Using the Collections.unmodifiable methods.

import net.mindview.util.Countries;

import java.util.*;

import static net.mindview.util.Print.print;

/**
* Created by JT on 2016/7/22.
*/
public class ReadOnly {
static Collection<String> data = new ArrayList<String>(Countries.names(6));

public static void main(String[] args) {
Collection<String> c = Collections.unmodifiableCollection(new ArrayList<String>(data));
print(c); // Reading is OK
//! c.add("one"); // Can't change it

List<String> a = Collections.unmodifiableList(new ArrayList<String>(data));
ListIterator<String> lit = a.listIterator();
print(lit.next()); // Reading is OK
//! lit.add("one"); // Can'tchange it

Set<String> s = Collections.unmodifiableSet(new HashSet<String>(data));
print(s); // Reading is OK
//! s.add("one"); // Can't change it

// For a SortedSet:
Set<String> ss = Collections.unmodifiableSortedSet(new TreeSet<String>(data));

Map<String, String> m = Collections.unmodifiableMap(new HashMap<String, String>(Countries.capitals(6)));
print(m); // Reading is OK
//! m.put("Ralph","Howdy!");

// For a SortedMap:
Map<String, String> sm = Collections.unmodifiableSortedMap(new TreeMap<String, String>(Countries.capitals(6)));
}
}


无论哪种情况,在将容器设为只读之前,必须填入有意义的数据。装载数据后,就应该使用“不可修改的”方法返回的引用去替换掉原本的引用。这样,就不用担心无意中修改了只读的内容。另一方面,此方法允许你保留一份可修改的容器,作为类的 private 成员,然后通过某个方法调用返回对该容器的“只读”的引用。这样一来,就只有你可以修改容器的内容,而别人只能读取。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息