Java集合(3):使用Abstract类

每个java.util容器都有其自己的Abstract类,它们提供了该容器接口的部分实现。下面是一个定制自己的Map的例子(List set就省略了):

定制自己的Map实现AbstractMap-->Map,需要实现[Set<Map.Entry<K,V>> entrySet()]方法

实现[Set<Map.Entry<K,V>> entrySet()]方法分两步:

(1) 实现Set<E>接口

(2) 实现Map.Entry<K,V>接口

  1 import java.util.AbstractMap;
  2 import java.util.AbstractSet;
  3 import java.util.ArrayList;
  4 import java.util.HashMap;
  5 import java.util.HashSet;
  6 import java.util.Hashtable;
  7 import java.util.Iterator;
  8 import java.util.LinkedHashMap;
  9 import java.util.LinkedHashSet;
 10 import java.util.LinkedList;
 11 import java.util.List;
 12 import java.util.Map;
 13 import java.util.Set;
 14 import java.util.TreeMap;
 15 import java.util.TreeSet;
 16
 17 class Countries {
 18     public static final String[][] DATA = {
 19             // Africa
 20             { "SOUTH AFRICA", "Cape Town" }, { "SUDAN", "Khartoum" },
 21             // Asia
 22             { "CHINA", "Beijing" }, { "JAPAN", "Tokyo" }, { "SOUTH KOREA", "Seoul" },
 23             // Australia and Oceania
 24             { "AUSTRALIA", "Canberra" }, { "NEW ZEALAND", "Wellington" },
 25             // Europe
 26             { "UNITED KINGDOM", "London" }, { "FRANCE", "Paris" }, { "GERMANY", "Berlin" }, { "ITALY", "Rome" },
 27             { "SPAIN", "Madrid" },
 28             // North and Central America
 29             { "UNITED STATES OF AMERICA", "Washington, D.C." }, { "CANADA", "Ottawa" },
 30             // South America
 31             { "BRAZIL", "Brasilia" }, { "ARGENTINA", "Buenos Aires" } };
 32
 33     private static class FlyweightMap extends AbstractMap<String, String> {
 34
 35         private final int dataLength;
 36
 37         private static Set<Map.Entry<String, String>> entries = new EntrySet(DATA.length);
 38
 39         public FlyweightMap() {
 40             dataLength = 0;
 41         }
 42
 43         public FlyweightMap(int dataLength) {
 44             this.dataLength = dataLength;
 45         }
 46
 47         @Override
 48         public Set<Map.Entry<String, String>> entrySet() {
 49             if (dataLength > 0) {
 50                 return new EntrySet(dataLength);
 51             }
 52             return entries;
 53         }
 54
 55         // (1) 实现Set<E>接口
 56         // 定制自己的Set实现AbstractSet(AbstractCollection)-->Set, 需要实现[Iterator<E> iterator() & int size()]方法
 57         private static class EntrySet extends AbstractSet<Map.Entry<String, String>> {
 58             private int size;
 59
 60             EntrySet(int size) {
 61                 this.size = size < 0 ? (this.size = 0)
 62                         : (size > DATA.length ? (this.size = DATA.length) : (this.size = size));
 63             }
 64
 65             @Override
 66             public int size() {
 67                 return size;
 68             }
 69
 70             @Override
 71             public Iterator<Map.Entry<String, String>> iterator() {
 72                 return new Iterator<Map.Entry<String, String>>() {
 73                     // Only one Entry object per Iterator:
 74                     private Entry entry = new Entry(-1);
 75
 76                     @Override
 77                     public boolean hasNext() {
 78                         return entry.index < size - 1;
 79                     }
 80
 81                     @Override
 82                     public java.util.Map.Entry<String, String> next() {
 83                         entry.index++;
 84                         return entry;
 85                     }
 86                 };
 87             }
 88         }
 89
 90         // (2) 实现Map.Entry<K,V>接口
 91         // 定制自己的Map.Entry实现Map.Entry<K, V>接口, 需要实现下面的方法
 92         // 每个Map.Entry对象都只存了它们的索引,而不是实际的键值。当调用getKey(), getValue()时,才会用索引返回恰当的元素
 93         private static class Entry implements Map.Entry<String, String> {
 94             int index;
 95
 96             Entry(int index) {
 97                 this.index = index;
 98             }
 99
100             @Override
101             public boolean equals(Object o) {
102                 return DATA[index][0].equals(o);
103             }
104
105             @Override
106             public String getKey() {
107                 return DATA[index][0];
108             }
109
110             @Override
111             public String getValue() {
112                 return DATA[index][1];
113             }
114
115             @Override
116             public String setValue(String value) {
117                 throw new UnsupportedOperationException();
118             }
119
120             @Override
121             public int hashCode() {
122                 return DATA[index][0].hashCode();
123             }
124         }
125     }
126
127     // 取Map全部内容
128     public static Map<String, String> capitals() {
129         return selectAll();
130     }
131
132     // 取Map全部内容的key
133     public static List<String> names() {
134         return new ArrayList<String>(capitals().keySet());
135     }
136
137     // 取Map部分内容
138     public static Map<String, String> capitals(final int size) {
139         return select(size);
140     }
141
142     // 取Map部分内容的key
143     public static List<String> names(int size) {
144         return new ArrayList<String>(select(size).keySet());
145     }
146
147     private static Map<String, String> selectAll() {
148         return new FlyweightMap();
149     }
150
151     private static Map<String, String> select(final int size) {
152         return new FlyweightMap(size);
153     }
154 }
155
156 public class Test4 {
157     public static void main(String[] args) {
158         System.out.println(Countries.capitals(5)); // {SOUTH AFRICA=Cape Town, SUDAN=Khartoum, CHINA=Beijing, JAPAN=Tokyo, SOUTH KOREA=Seoul}
159         System.out.println(Countries.names(5)); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN, SOUTH KOREA]
160         System.out.println(new HashMap<String, String>(Countries.capitals(3))); // {SUDAN=Khartoum, CHINA=Beijing, SOUTH AFRICA=Cape Town}
161         System.out.println(new LinkedHashMap<String, String>(Countries.capitals(3))); // {SOUTH AFRICA=Cape Town, SUDAN=Khartoum, CHINA=Beijing}
162         System.out.println(new TreeMap<String, String>(Countries.capitals(3))); // {CHINA=Beijing, SOUTH AFRICA=Pretoria/Cape Town, SUDAN=Khartoum}
163         System.out.println(new Hashtable<String, String>(Countries.capitals(3))); // {SUDAN=Khartoum, SOUTH AFRICA=Pretoria/Cape Town, CHINA=Beijing}
164         System.out.println(new HashSet<String>(Countries.names(4))); // [SUDAN, CHINA, SOUTH AFRICA, JAPAN]
165         System.out.println(new LinkedHashSet<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN]
166         System.out.println(new TreeSet<String>(Countries.names(4))); // [CHINA, JAPAN, SOUTH AFRICA, SUDAN]
167         System.out.println(new ArrayList<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN]
168         System.out.println(new LinkedList<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN]
169         System.out.println(Countries.capitals().get("BRAZIL")); // Brasilia
170     }
171 }

原文地址:https://www.cnblogs.com/storml/p/8434323.html

时间: 2024-11-13 10:56:17

Java集合(3):使用Abstract类的相关文章

Java集合中的LinkedHashMap类

jdk1.8.0_144 本文阅读最好先了解HashMap底层,可前往<Java集合中的HashMap类>. LinkedHashMap由于它的插入有序特性,也是一种比较常用的Map集合.它继承了HashMap,很多方法都直接复用了父类HashMap的方法.本文将探讨LinkedHashMap的内部实现,以及它是如何保证插入元素是按插入顺序排序的. 在分析前可以先思考下,既然是按照插入顺序,并且以Linked-开头,就很有可能是链表实现.如果纯粹以链表实现,也不是不可以,LinkedHashM

【JAVA集合框架之工具类】

一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public class Collections extends Object 全类名:java.util.Collections public class Arrays extends Object 全类名:java.util.Arrays 二.Collections类. 1.Collections.sort

Java集合框架之LinkedList类

ArrayList用数组作为其保存元素的数据结构,而LinkedList采用的是链表的数据结构.而ArrayList和LinkedList都是线性表list.但LinkedList并不具备随机访问能力,而ArrayList拥有. 对于链表集合,首先(1)我们使用API里现成的LinkedList类来进行一些分析,之后(2)我们再用自身的java代码实现链表及其LinkedList中相对应的方法. (1)现成API接口的分析使用 定义如下,与ArrayList类似. LinkedList<Stri

java集合:java集合详解及类关系图

List和Set继承自Collection接口. Set无序不允许元素重复.HashSet和TreeSet是两个主要的实现类. List有序且允许元素重复,支持null对象.ArrayList.LinkedList和Vector是三个主要的实现类. Map也属于集合系统,但和Collection接口没关系.Map是key对value的映射集合,其中key列就是一个集合.key不能重复,但是value可以重复.HashMap.TreeMap和Hashtable是三个主要的实现类. SortedSe

Java集合框架之ArrayList类

ArrayList是一个泛型数据结构,即对象/引用类型是在<E>里进行确定的(E中定义的必须是对象/引用).例如,定义一个字符串类型的ArrayList为如下格式: ArrayList<String> test = new ArrayList<String>(); 我们可以看出,ArrayList<String>被看成了一个整体. 下面我们看一个简单的例子.代码如下: import java.util.ArrayList; public class Arra

异常处理、常用类、Java集合框架、反射

异常处理: 1.  异常:程序在执行过程中所产生的问题. 异常的三种类:①检查异常:又叫checdked异常或者受检异常.通常是用户错误或者不能被程序员所预见的问题.检查异常需要被解决之后才能通过编译. ②运行时异常:程序在运行过程中可能发生的.可以被程序员所避免的异常类型. ③错误:事实上错误不是异常,但却是用户和程序员无法控制的问题. 2.  异常的控制流程: 异常是被一个方法抛出的对象. (1) 处理异常的三个方法:①捕获这个异常,不让它沿着调用栈继续向下抛. ②捕获这个异常,并继续向下抛

Java集合框架--List、Set、Map

Java集合框架接口和类的层次结构: java.util.Collection [I] +--java.util.List [I] +--java.util.ArrayList [C] +--java.util.LinkedList [C] +--java.util.Vector [C] +--java.util.Stack [C] +--java.util.Set [I] +--java.util.HashSet [C] +--java.util.SortedSet [I] +--java.u

跟王老师学集合(一)为什么要使用集合和Java集合概述

为什么要使用集合和Java集合概述 主讲人:王少华  QQ群号:483773664 学习目标 1 理解为什么使用集合 2 掌握Java集合框架 一.使用数组缺陷: 在电子宠物系统中,如果想存储多个宠物信息,可以使用数组来实现.例如,可以定义一个长度50的Dog类型的数组,存储多个Dog对象的信息.但是采用数组存在以下一些明显的缺陷: 数组长度固定不变,不能很好适应元素数量动态变化的情况.若要存储大于50个狗狗的信息,则数组长度不足:若只存储20个狗狗的信息,则造成内存空间浪费 可通过数组名.le

java 容器深入研究之使用Abstract类定制

package org.rui.collection3.map; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Linke