Thinking in Java:第十七章-容器深入研究

1:继承AbstractList实现自己的List:CountIntegerList
public class CountIntegerList extends AbstractList<Integer>{

    private int size;

    public CountIntegerList(int size) {
        this.size = (size < 0 ? 0 : size);
    }

    @Override
    public Integer get(int index) {
        return Integer.valueOf(index + 2);
    }

    @Override
    public int size() {
        return size;
    }

    public static void main(String[] args) {
        System.out.println(new CountIntegerList(10));
        CountIntegerList l = new CountIntegerList(10);
        System.out.println(l.get(2));;
    }
}
2:继承AbstractMap实现自己的Map:CountingMapData
public class CountingMapData extends AbstractMap<Integer, String> {

    private int size;
    private static String[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

    public CountingMapData(int size) {
        this.size = (size < 0 ? 0 : size);
    }

    private static class Entry implements Map.Entry<Integer, String> {
        int index;

        public Entry(int index) {
            this.index = index;
        }

        @Override
        public boolean equals(Object obj) {
            return Integer.valueOf(index).equals(obj);
        }

        @Override
        public Integer getKey() {
            return index;
        }

        @Override
        public String getValue() {
            return chars[index % chars.length] + Integer.toString(index / chars.length);
        }

        @Override
        public String setValue(String value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public int hashCode() {
            return Integer.valueOf(index).hashCode();
        }
    }


    @Override
    public Set<Map.Entry<Integer, String>> entrySet() {
        Set<Map.Entry<Integer, String>> entries = new LinkedHashSet<Map.Entry<Integer, String>>();
        for (int i = 0; i < size; i++) {
            entries.add(new Entry(i));
        }
        return entries;
    }

    public static void main(String[] args) {
        System.out.println(new CountingMapData(30));
    }
}
3:Map的最基本的实现,简单的关联数组:AssociativeArray
public class AssociativeArray<K, V> {

    private int index;
    private Object[][] pairs;

    public AssociativeArray(int length) {
        pairs = new Object[length][2];
    }

    public void put(K key, V value) {
        if (index > pairs.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        pairs[index ++] = new Object[]{key, value};
    }

    public <K> V get(K key) {
        for (int i = 0; i < index; i++) {
            if (key.equals(pairs[i][0])) {
                return (V)pairs[i][1];
            }
        }
        return null;
    }

    @Override
    public String toString() {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < index; i++) {
            result.append(pairs[i][0]).append(":").append(pairs[i][1]).append(",");
        }
        result.deleteCharAt(result.length()-1);
        result.append("\n");
        return result.toString();
    }

    public static void main(String[] args) {
        AssociativeArray<Integer, String> in = new AssociativeArray<Integer, String>(1);
        in.put(1, "stay");
        in.put(2, "hungry");
        System.out.println(in);
    }
}
4: 演示TreeMap 的简单功能:SortedMapDemo
public class SortedMapDemo {

    public static void main(String[] args) {
        TreeMap<Integer, String> map = new TreeMap<Integer, String>(new CountingMapData(10));
        System.out.println(map);
        // 按键的大小排序
        map.put(12, "D1");
        map.put(11, "D2");
        System.out.println(map);
        System.out.println(map.firstKey());
        System.out.println(map.lastEntry());
        int low = 3;
        int high = 6;
        System.out.println(map.subMap(low, high));
        System.out.println(map.headMap(high));
        System.out.println(map.tailMap(low));


        List<String> list = new ArrayList<String>();
        list.set(3, "avc");

    }
}
5:演示LinkedHashMap的LRU功能,:LinkedHashMapDemo
public class LinkedHashMapDemo {

    public static void main(String[] args) {
        LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>(new CountingMapData(9));

        System.out.println(map);

        // least-recently-used order, LRU算法
        map = new LinkedHashMap<Integer, String>(16, 0.75f, true);
        map.putAll(new CountingMapData(9));
        System.out.println(map);
        for (int i = 0; i < 6; i++) {
            map.get(i);
        }
        System.out.println(map);
        map.get(0);
        System.out.println(map);
    }
}
6:hashcode(),散列将键保存在某处,以便能够很快的找到。存储一组元素最快的数据结构是数组,所以使用它来表示键的信息,(注意,是键的信息,而不是键本身)。但是数组又不能调整容量,于是,设计为数组不保存键本身,而是通过键对象生成一个数字,将其作为数组的下标,这个数字就是散列码,由定义在Object中,且可能被你的类覆盖的hashCode()方法生成。不同的键可以产生相同的下标,也就是说,可能会有冲突,于是查询一个值的过程就是先计算散列码,然后使用散列码查询数组。数组并不直接保存值,而是保存值的List。然后对list中的值使用equals()方法进行线性查询。因此,不是查询整个List,而是直接跳到数组的某个位置,只对很少的元素进行比较,这便是HashMap如此快的原因:SimpleHashMap
public class SimpleHashMap<K, V> extends AbstractMap<K, V> {

    static final int SIZE = 997;

    LinkedList<MapEntry<K, V>>[] buckets = new LinkedList[SIZE];

    public V put(K key, V value) {
        V oldValue = null;
        int index = Math.abs(key.hashCode()) % SIZE;
        if (buckets[index] == null) {
            buckets[index] = new LinkedList<MapEntry<K, V>>();
        }
        LinkedList<MapEntry<K, V>> bucket = buckets[index];
        MapEntry<K, V> pair = new MapEntry<>(key, value);
        ListIterator<MapEntry<K, V>> it = bucket.listIterator();
        boolean found = false;
        while (it.hasNext()) {
            MapEntry<K, V> next = it.next();
            if (next.getKey().equals(key)) {
                oldValue = next.getValue();
                it.set(pair);  // replace old with new
                found = true;
            }
        }

        if (!found) {
            buckets[index].add(pair);
        }
        return oldValue;
    }

    // 这里是Object,不是K
    public V get(Object key) {
        int index = Math.abs(key.hashCode()) % SIZE;
        if (buckets[index] ==  null) {
            return null;
        }
        for (MapEntry<K, V> entry : buckets[index]) {
            if (entry.getKey().equals(key)) {
                return entry.getValue();
            }
        }
        return null;
    }

    public Set<Map.Entry<K, V>> entrySet() {
        Set<Map.Entry<K, V>> set = new HashSet<Entry<K, V>>();
        for (LinkedList<MapEntry<K, V>> bucket : buckets) {
            if (bucket == null) {
                continue;
            }
            for (MapEntry<K, V> entry : bucket) {
                set.add(entry);
            }
        }
        return set;
    }

    public static void main(String[] args) {
        SimpleHashMap<Integer, String> hashMap = new SimpleHashMap<Integer, String>();
        hashMap.putAll(new CountingMapData(10));
        System.out.println(hashMap);
        System.out.println(hashMap.get(1));
        System.out.println(hashMap);

        HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.putAll(new CountingMapData(10));
        System.out.println(map);
    }
}
散列表中槽位(slot)通常称为桶(bucket),Java桶的理想容量是2的幂次方,这与现代处理器,在处理除法和取余数是最慢的操作有关。
7:hashCode()的实例:Individual
public class Individual implements Comparable<Individual> {

    public static long counter = 0;
    private final long id = counter ++;
    private String name;

    public Individual(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + (name == null ? "" : " " + name);
    }

    public long id() {return id;}

    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Individual) && (id == ((Individual) obj).id);
    }

    @Override
    public int hashCode() {
        int result = 17;
        if (name != null) {
            result = 37 * result + name.hashCode();
        }
        result = 37 * result + (int)id;
        return result;
    }

    @Override
    public int compareTo(Individual arg) {
        String first = getClass().getSimpleName();
        String argFirst = arg.getClass().getSimpleName();
        int firstCompare = first.compareTo(argFirst);
        if (firstCompare != 0) {
            return firstCompare;
        }
        if (name != null && arg.name != null) {
            int secondCompare = name.compareTo(arg.name);
            if (secondCompare != 0) {
                return secondCompare;
            }
        }
        return (arg.id() < id ? 1 : (arg.id() == id ? 0 : -1));
    }

    public static void main(String[] args) {
        List<Individual> list = new ArrayList<Individual>();
        for (int i = 0; i < 10; i++) {
            Individual a = new Individual(Integer.valueOf(i).toString());
            list.add(a);
            System.out.println(a);
        }

        Individual individual = list.get(1);
        Individual individual1 = list.get(3);
        Individual individual11 = new Individual("1");
        System.out.println(individual.compareTo(individual1));
        System.out.println(individual.compareTo(individual11));


    }
}
8::实现的选择,略过
9:Collections.unmodifiableCollection() 实例:ReadOnly
public class ReadOnly {

    static Collection<String> data = new ArrayList<String>();


    public static void main(String[] args) {

        data.add("china");
        data.add("japan");
        data.add("american");

        Collection<String> c = Collections.unmodifiableCollection(new ArrayList<String>(data));
        System.out.println(c); // readonly is ok

        List<String> a = Collections.unmodifiableList(new ArrayList<String>(data));  // readonly is ok
        // ...
    }
}
10:Collections.synchronizedCollection()实例:Synchronization
public class Synchronization {

    public static void main(String[] args) {
        Collection<String> c = Collections.synchronizedCollection(new ArrayList<String>());

        List<String> l = Collections.synchronizedList(new ArrayList<String>());

        Set<String> ss = Collections.synchronizedSet(new HashSet<String>());

        Map<String, String> ms = Collections.synchronizedMap(new TreeMap<String, String>());
    }
}
11:Java容器类采用了快速报错的机制,它会探查容器上任何除了你的进程所进行的操作之外的改变,一旦发现其他进程修改了容器,就会抛出ConcurrentModificationException
12:总结。。。Java的容器是基于复杂性的利弊和仔细权衡的产物。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值