每个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>接口

 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.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet; class Countries {
public static final String[][] DATA = {
// Africa
{ "SOUTH AFRICA", "Cape Town" }, { "SUDAN", "Khartoum" },
// Asia
{ "CHINA", "Beijing" }, { "JAPAN", "Tokyo" }, { "SOUTH KOREA", "Seoul" },
// Australia and Oceania
{ "AUSTRALIA", "Canberra" }, { "NEW ZEALAND", "Wellington" },
// Europe
{ "UNITED KINGDOM", "London" }, { "FRANCE", "Paris" }, { "GERMANY", "Berlin" }, { "ITALY", "Rome" },
{ "SPAIN", "Madrid" },
// North and Central America
{ "UNITED STATES OF AMERICA", "Washington, D.C." }, { "CANADA", "Ottawa" },
// South America
{ "BRAZIL", "Brasilia" }, { "ARGENTINA", "Buenos Aires" } }; private static class FlyweightMap extends AbstractMap<String, String> { private final int dataLength; private static Set<Map.Entry<String, String>> entries = new EntrySet(DATA.length); public FlyweightMap() {
dataLength = 0;
} public FlyweightMap(int dataLength) {
this.dataLength = dataLength;
} @Override
public Set<Map.Entry<String, String>> entrySet() {
if (dataLength > 0) {
return new EntrySet(dataLength);
}
return entries;
} // (1) 实现Set<E>接口
// 定制自己的Set实现AbstractSet(AbstractCollection)-->Set, 需要实现[Iterator<E> iterator() & int size()]方法
private static class EntrySet extends AbstractSet<Map.Entry<String, String>> {
private int size; EntrySet(int size) {
this.size = size < 0 ? (this.size = 0)
: (size > DATA.length ? (this.size = DATA.length) : (this.size = size));
} @Override
public int size() {
return size;
} @Override
public Iterator<Map.Entry<String, String>> iterator() {
return new Iterator<Map.Entry<String, String>>() {
// Only one Entry object per Iterator:
private Entry entry = new Entry(-1); @Override
public boolean hasNext() {
return entry.index < size - 1;
} @Override
public java.util.Map.Entry<String, String> next() {
entry.index++;
return entry;
}
};
}
} // (2) 实现Map.Entry<K,V>接口
// 定制自己的Map.Entry实现Map.Entry<K, V>接口, 需要实现下面的方法
// 每个Map.Entry对象都只存了它们的索引,而不是实际的键值。当调用getKey(), getValue()时,才会用索引返回恰当的元素
private static class Entry implements Map.Entry<String, String> {
int index; Entry(int index) {
this.index = index;
} @Override
public boolean equals(Object o) {
return DATA[index][0].equals(o);
} @Override
public String getKey() {
return DATA[index][0];
} @Override
public String getValue() {
return DATA[index][1];
} @Override
public String setValue(String value) {
throw new UnsupportedOperationException();
} @Override
public int hashCode() {
return DATA[index][0].hashCode();
}
}
} // 取Map全部内容
public static Map<String, String> capitals() {
return selectAll();
} // 取Map全部内容的key
public static List<String> names() {
return new ArrayList<String>(capitals().keySet());
} // 取Map部分内容
public static Map<String, String> capitals(final int size) {
return select(size);
} // 取Map部分内容的key
public static List<String> names(int size) {
return new ArrayList<String>(select(size).keySet());
} private static Map<String, String> selectAll() {
return new FlyweightMap();
} private static Map<String, String> select(final int size) {
return new FlyweightMap(size);
}
} public class Test4 {
public static void main(String[] args) {
System.out.println(Countries.capitals(5)); // {SOUTH AFRICA=Cape Town, SUDAN=Khartoum, CHINA=Beijing, JAPAN=Tokyo, SOUTH KOREA=Seoul}
System.out.println(Countries.names(5)); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN, SOUTH KOREA]
System.out.println(new HashMap<String, String>(Countries.capitals(3))); // {SUDAN=Khartoum, CHINA=Beijing, SOUTH AFRICA=Cape Town}
System.out.println(new LinkedHashMap<String, String>(Countries.capitals(3))); // {SOUTH AFRICA=Cape Town, SUDAN=Khartoum, CHINA=Beijing}
System.out.println(new TreeMap<String, String>(Countries.capitals(3))); // {CHINA=Beijing, SOUTH AFRICA=Pretoria/Cape Town, SUDAN=Khartoum}
System.out.println(new Hashtable<String, String>(Countries.capitals(3))); // {SUDAN=Khartoum, SOUTH AFRICA=Pretoria/Cape Town, CHINA=Beijing}
System.out.println(new HashSet<String>(Countries.names(4))); // [SUDAN, CHINA, SOUTH AFRICA, JAPAN]
System.out.println(new LinkedHashSet<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN]
System.out.println(new TreeSet<String>(Countries.names(4))); // [CHINA, JAPAN, SOUTH AFRICA, SUDAN]
System.out.println(new ArrayList<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN]
System.out.println(new LinkedList<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN]
System.out.println(Countries.capitals().get("BRAZIL")); // Brasilia
}
}

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

  1. Java集合框架(常用类) JCF

    Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...

  2. Java最重要的21个技术点和知识点之JAVA集合框架、异常类、IO

    (三)Java最重要的21个技术点和知识点之JAVA集合框架.异常类.IO  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享 ...

  3. Java集合中的LinkedHashMap类

    jdk1.8.0_144 本文阅读最好先了解HashMap底层,可前往<Java集合中的HashMap类>. LinkedHashMap由于它的插入有序特性,也是一种比较常用的Map集合. ...

  4. 【JAVA集合框架之工具类】

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

  5. JAVA集合四:比较器--类自定义排序

    参考链接: HOW2J.CN 前言 对于JAVA集合,都能够用集合的工具类Collections 提供的方法: Collections.sort(List list) Collections.sort ...

  6. java集合(1)- 类底层数据结构分析

    Java 集合类图 参考:http://www.cnblogs.com/xwdreamer/archive/2012/05/30/2526822.html

  7. Java集合中的HashMap类

    jdk1.8.0_144 HashMap作为最常用集合之一,继承自AbstractMap.JDK8的HashMap实现与JDK7不同,新增了红黑树作为底层数据结构,结构变得复杂,效率变得更高.为满足自 ...

  8. 1、java集合:java集合详解及类关系图

    List和Set继承自Collection接口. Set无序不允许元素重复.HashSet和TreeSet是两个主要的实现类. List有序且允许元素重复,支持null对象.ArrayList.Lin ...

  9. Java技术——Interface与abstract类的区别

    )抽象类是对类抽象,是面向整个类的自下而上的设计理念,一般是先有各种子类,再有把这些有关系的子类加以抽象为父类的需求.而接口是对行为的抽象,是面向行为的自上而下的设计理念,接口根本就不需要知道子类的存 ...

  10. Java 集合源码解析(1):Iterator

    Java, Android 开发也有段时间了,当初为了早点学 Android,Java 匆匆了解个大概就结束了,基础不够扎实. 虽然集合框架经常用,但是一直没有仔细看看原理,仅止于会用,不知道为什么要 ...

随机推荐

  1. solr 分面搜索(转载)

    原文地址:http://blog.csdn.net/bingduanlbd/article/details/52199347 分面搜索(Faceting)基于索引词项对搜索结果进行分类,同时返回每个分 ...

  2. zabbix内存溢出解决方法

    1406:20180802:183248.783 __mem_malloc: skipped 0 asked 48 skip_min 4294967295 skip_max 0 1406:201808 ...

  3. CentOS7下tftp服务安装配置

    1.软件包安装 root用户或者普通用户使用sudo权限执行如下命令: yum install xinetd tftp tftp-server # root 用户执行 sudo yum install ...

  4. BZOJ 2458: [BeiJing2011]最小三角形 (分治)

    分治就是了. 类似于分治找最近/远点对. CODE #include <bits/stdc++.h> using namespace std; const double eps = 1e- ...

  5. Mybatis的mapper接口在Spring中实例化过程

    在spring中使用mybatis时一般有下面的配置 <bean id="mapperScannerConfigurer" class="org.mybatis.s ...

  6. EasyLogging++学习笔记(1)—— 简要介绍

    对于有开发经验的程序员来说,记录程序执行日志是一件必不可少的事情.通过查看和分析日志信息,不仅可以有效地帮助我们调试程序,而且当程序正式发布运行之后,更是可以帮助我们快速.准确地定位问题.在现在这个开 ...

  7. SQL基础练习03---牛客网

    目录 1 创建一个actor表 2 批量插入数据 3 批量插入数据不用replace 4 创建一个actor_name表 5 对first_name创建唯一索引 6 针对actor表创建视图actor ...

  8. web自动化之前端知识

    下面这种写法只作用于这1个标签:  下面这种也是比较老的写法:  下面是常用的方式:把一个css样式放入到一个文件中,然后引用: 第三方引用的css一般是压缩过的,这样静态资源加载速度会比较快.  如 ...

  9. Verilog写入变量值到文件语句

    integer signed fid_out1,fid_out2; initial begin fid_out1 = $fopen("dataout_i.txt","w& ...

  10. ThinkPHP,page,paginate后台分页翻页时保留检索条件的方法

    paginate(20,false,['query'=>request()->param()]);   20是每页显示行数 示例代码:  $list = Db::name('article ...