Thinking in Java 第17章 容器深入研究(17.10-17.14)
2016-07-22 08:58
821 查看
//声明:部分内容引自《Java编程思想(第四版)》机械工业出版社
– 容器之间的区别通常是:所使用的接口是由什么样的数据结构实现的。
例:ArrayList 和 LinkedList都实现了 List 接口,但 ArrayList 底层由数组支持,而 LinkedList 由双向链表实现。所以,如果要经常在表中插入或删除元素,LinkedList 比较合适,否则,应使用速度更快的 ArrayList。
例:Set 被可实现为 TreeSet、HashSet 或 LinkedSet。HashSet 最常用,查询速度最快;LinkedHashSet 保持元素插入的次序;TreeSet 基于 TreeMap,生成一个总是处于排序状态的 Set。
– List 的排序和查询。
– 设定 Collection 或 Map 为不可修改。
无论哪种情况,在将容器设为只读之前,必须填入有意义的数据。装载数据后,就应该使用“不可修改的”方法返回的引用去替换掉原本的引用。这样,就不用担心无意中修改了只读的内容。另一方面,此方法允许你保留一份可修改的容器,作为类的 private 成员,然后通过某个方法调用返回对该容器的“只读”的引用。这样一来,就只有你可以修改容器的内容,而别人只能读取。
【连接接口的不同实现】
– 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 成员,然后通过某个方法调用返回对该容器的“只读”的引用。这样一来,就只有你可以修改容器的内容,而别人只能读取。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树