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

//声明:部分内容引自《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;//: containers/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 成员,然后通过某个方法调用返回对该容器的“只读”的引用。这样一来,就只有你可以修改容器的内容,而别人只能读取。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值