Collections Framework中的算法(之三)--不可变装饰器相关
本篇主要讲述Collections类中的unmodifiable相关的方法!这些方法都有一个共同含义就是使用此方法创建的对象都是不可变的!典型的装饰器模式的应用!下面的几篇都是装饰器模式在Java
Collections Framework中的典型应用!同时还简要叙说了如何理解内部类!
12.1装饰器模式基础
装饰器模式是GOF那本书中提到的23个经典设计模式中的一个比较常用的模式!
Decorator Pattern――Attatches
additional responsibilities to an object dynamically .Derocators provide a flexible alternative to subclassing for extending functionality .
以上是设计模式的意图!即动态地为对象增加某些额外的功能。同时装饰器模式提供了一种取代继承的扩展类功能的方法!我们的不可变装饰器、同步装饰器……等都是装饰器的应用。装饰器模式在Java中最著名的应用在IO包中,其次就是在我们的util包中!我会在博客的设计模式一栏目中以个人的观点详细讲述各种设计模式!讲Decorator模式时会举一个三明治的装饰器的例子!好像有人讲过!不过我可不会抄袭哦!离开那些东西,自己写自己的!不过难免雷同!为了避免抄袭的嫌疑,我会举一个目前书中都没有的,自创的例子!通过本例子我会讲Decorator模式再次细分!至于什么例子,已经设想好了!保密起见!大家关注吧!
以上是装饰器模式的意图,下面是装饰器模式的特点:在装饰器模式中所有的被装饰对象都和装饰器有同样的接口!不信,可以先看看IO包的Source
Code !
12.2不可变集合
//对某个Collection使用unmodifiableCollection方法得到一个Collection对象
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
return new UnmodifiableCollection<T>(c);
//返回的是一个实现某个接口的类,而该方法需要返回的是一个接口
//这是典型的工厂方法模式的应用!对于模式我会在博客中其它栏目中详细讲述!
}
static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
//这就是不可变Collection的核心类
private static final long serialVersionUID = 1820017752578914078L;
Collection<? extends E> c; //该类有一个被装饰对象作为属性,装饰器的要求
UnmodifiableCollection(Collection<? extends E> c) { //通过构造方法传入这个被装饰的对象
if (c==null) throw new NullPointerException();
this.c = c;
}
public int size(){ return c.size(); }
//装饰器类中实现与被装饰器对象同样的接口
//这些方法的实现有着极其鲜明的特点:肯定会调用被装饰对象的相近的方法
public boolean isEmpty(){ return c.isEmpty(); }
public boolean contains(Object o) { return c.contains(o); }
public Object[] toArray(){ return c.toArray(); }
public <T> T[] toArray(T[] a) { return c.toArray(a); }
public String toString(){ return c.toString(); }
public boolean containsAll(Collection<?> coll) { return c.containsAll(coll); }
//上面这些方法的共同特点是,不会改变被装饰对象的内部状态,
//因此他们完完全全应用了被装饰对象的方法。全调用被装饰对象的方法,就没有什么意义了
//下面的这些方法有些不一样了,屏蔽了被装饰对象的方法
//这些被屏蔽的方法有一个共同点就是:屏蔽那些可能改变集合内部状态的方法!
//合乎装饰器模式的意图吧!我们的不可变装饰器就是为了使被装饰对象不可以改变
//以下这些方法的实现都有一个共同点:
//只要改变状态都会抛出异常UnsupportedOperationException()
public boolean add(E o){
throw new UnsupportedOperationException();
}
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
public boolean addAll(Collection<? extends E> coll) {
throw new UnsupportedOperationException();
}
public boolean removeAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public boolean retainAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
}
public Iterator<E> iterator() {
return new Iterator<E>() {
Iterator<? extends E> i = c.iterator();
public boolean hasNext() { return i.hasNext(); }
public E next({ return i.next(); }
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
//上面的iterator是个遍历器模式的应用!在Java
Collections Framework中应用很广泛哦!
//同时他也是一个内部类!我分几步向你展示这个内部类的写法吧!
//1.public Iterator iterator(){ }能看懂吧!要返回一个实现Iterator接口的对象
//2.创建并返回这个Iterator对象 return
new Iterator(){ },这可是一个没有名称的内部类哦!
// 这一步很难理解的!Iterator()是一个实现Iterator接口的没有名称的类的构造器,
// 并且参数为空。返回其它非接口的抽象类也是这样的!看下面其它的代码分析吧!
//3.内部类也是一个类,我的该类肯定要实现这个接口中所有的方法的!以下就是实现了;
// public boolean hasNext() { ; }
// public E next({ ; }
// public void remove() { ; }
//填入相应的代码,实现这些方法就行!
上面我简单地谈了一个简单的内部类,具体的博客中其它文章,会全面总结内部类的!希望大家关注吧!会分析是个基础,会用才是目的!
12.3不可变Set
//这个我就不用讲了吧!
public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
return new UnmodifiableSet<T>(s);
}
//在框架中Set继承至Collection,这里也是这个关系!研究吧!OO思想哦!
static class UnmodifiableSet<E> extends UnmodifiableCollection<E> implements Set<E>, Serializable {
private static final long serialVersionUID = -9215047833775013803L;
UnmodifiableSet(Set<? extends E> s) { super(s); }
public boolean equals(Object o) { return c.equals(o); }
public int hashCode() { return c.hashCode(); }
}
//上面主要是调用被装饰对象的方法!为什么啊!?你得看看Collection中得代码和说明
//万事都有由来的,人家注册都是有目的的!
12.4不可变SortedSet
//不讲了!仔细看吧!
public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
return new UnmodifiableSortedSet<T>(s);
}
static class UnmodifiableSortedSet<E> extends UnmodifiableSet<E> implements SortedSet<E>, Serializable {
private static final long serialVersionUID = -4929149591599911165L;
private SortedSet<E> ss;
UnmodifiableSortedSet(SortedSet<E> s) { super(s); ss = s; }
public Comparator<? super E> comparator() { return ss.comparator(); }
public SortedSet<E> subSet(E fromElement, E toElement) {
return new UnmodifiableSortedSet<E>(ss.subSet(fromElement,toElement));
}
public SortedSet<E> headSet(E toElement) {
return new UnmodifiableSortedSet<E>(ss.headSet(toElement));
}
public SortedSet<E> tailSet(E fromElement) {
return new UnmodifiableSortedSet<E>(ss.tailSet(fromElement));
}
public E first(){ return ss.first(); }
public E last(){ return ss.last(); }
}
12.5不可变List
//又是一个古老的话题!RandomAccessList和一般的List,除了多了一个没有任何方法的接口
//其它没有什么差别又是为什么呢!看看我《FailFast机制》的那篇的代码吧!
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<T>(list) :
new UnmodifiableList<T>(list));
}
static class UnmodifiableList<E> extends UnmodifiableCollection<E> implements List<E> {
static final long serialVersionUID = -283967356065247728L;
List<? extends E> list;
UnmodifiableList(List<? extends E> list) {
super(list);
this.list = list;
}
public boolean equals(Object o) { return list.equals(o); }
public int hashCode(){ return list.hashCode(); }
public E get(int index) { return list.get(index); }
public E set(int index, E element) { throw new UnsupportedOperationException(); }
public void add(int index, E element) { throw new UnsupportedOperationException(); }
public E remove(int index) { throw new UnsupportedOperationException(); }
public int indexOf(Object o) { return list.indexOf(o); }
public int lastIndexOf(Object o) { return list.lastIndexOf(o); }
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
public ListIterator<E> listIterator() {return listIterator(0);}
public ListIterator<E> listIterator(final int index) {
return new ListIterator<E>() {
ListIterator<? extends E> i = list.listIterator(index);
public boolean hasNext(){ return i.hasNext(); }
public E next(){ return i.next(); }
public boolean hasPrevious() { return i.hasPrevious(); }
public E previous(){ return i.previous(); }
public int nextIndex(){ return i.nextIndex(); }
public int previousIndex() { return i.previousIndex(); }
public void remove() {
throw new UnsupportedOperationException();
}
public void set(E o) {
throw new UnsupportedOperationException();
}
public void add(E o) {
throw new UnsupportedOperationException();
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
return new UnmodifiableList<E>(list.subList(fromIndex, toIndex));
}
private Object readResolve() {
return (list instanceof RandomAccess
? new UnmodifiableRandomAccessList<E>(list)
: this);
}
}
//同样的List具体实现中也有这种关系!
//RandomAccessList继承至某个具体的List同时实现RandomAccess接口
static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E> implements RandomAccess {
UnmodifiableRandomAccessList(List<? extends E> list) {
super(list);
}
public List<E> subList(int fromIndex, int toIndex) {
return new UnmodifiableRandomAccessList<E>( list.subList(fromIndex, toIndex));
}
private static final long serialVersionUID = -2542308836966382001L;
private Object writeReplace() {
return new UnmodifiableList<E>(list);
}
}
12.6不可变Map
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
return new UnmodifiableMap<K,V>(m);
}
private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = -1034234728574286014L;
private final Map<? extends K, ? extends V> m;
UnmodifiableMap(Map<? extends K, ? extends V> m) {
if (m==null) throw new NullPointerException();
this.m = m;
}
public int size(){ return m.size(); }
public boolean isEmpty(){ return m.isEmpty(); }
public boolean containsKey(Object key) { return m.containsKey(key); }
public boolean containsValue(Object val) { return m.containsValue(val); }
public V get(Object key) { return m.get(key); }
public V put(K key, V value) { throw new UnsupportedOperationException(); }
public V remove(Object key) { throw new UnsupportedOperationException(); }
public void putAll(Map<? extends K, ? extends V> t) { throw new UnsupportedOperationException(); }
public void clear() { throw new UnsupportedOperationException(); }
private transient Set<K> keySet = null;
private transient Set<Map.Entry<K,V>> entrySet = null;
private transient Collection<V> values = null;
public Set<K> keySet() {
if (keySet==null)
keySet = unmodifiableSet(m.keySet());
return keySet;
}
public Set<Map.Entry<K,V>> entrySet() {
if (entrySet==null)
entrySet = new UnmodifiableEntrySet<K,V>(m.entrySet());
return entrySet;
}
public Collection<V> values() {
if (values==null)
values = unmodifiableCollection(m.values());
return values;
}
public boolean equals(Object o) { return m.equals(o); }
public int hashCode(){ return m.hashCode(); }
public String toString(){ return m.toString(); }
static class UnmodifiableEntrySet<K,V> extends UnmodifiableSet<Map.Entry<K,V>> {
private static final long serialVersionUID = 7854390611657943733L;
UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {
super((Set<Map.Entry<K,V>>)(Set)s);
}
public Iterator<Map.Entry<K,V>> iterator() {
return new Iterator<Map.Entry<K,V>>() {
Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();
public boolean hasNext() {
return i.hasNext();
}
public Map.Entry<K,V> next() {
return new UnmodifiableEntry<K,V>(i.next());
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public Object[] toArray() {
Object[] a = c.toArray();
for (int i=0; i<a.length; i++)
a[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)a[i]);
return a;
}
public <T> T[] toArray(T[] a) {
Object[] arr = c.toArray(a.length==0 ? a :
(T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), 0));
for (int i=0; i<arr.length; i++)
arr[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)arr[i]);
if (arr.length > a.length)
return (T[])arr;
System.arraycopy(arr, 0, a, 0, arr.length);
if (a.length > arr.length) a[arr.length] = null;
return a;
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry)) return false;
return c.contains(new UnmodifiableEntry<K,V>((Map.Entry<K,V>) o));
}
public boolean containsAll(Collection<?> coll) {
Iterator<?> e = coll.iterator();
while (e.hasNext())
if (!contains(e.next())) return false;
return true;
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Set)) return false;
Set s = (Set) o;
if (s.size() != c.size()) return false;
return containsAll(s); // Invokes safe containsAll() above
}
//好多没有讲述了!现在看看斩草除根的做法!内部类的写方法也被禁止了!
private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> {
private Map.Entry<? extends K, ? extends V> e;
UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) { this.e = e; }
public K getKey(){ return e.getKey(); }
public V getValue() { return e.getValue(); }
public V setValue(V value) {
throw new UnsupportedOperationException();
}
public int hashCode() { return e.hashCode(); }
public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) return false;
Map.Entry t = (Map.Entry)o;
return eq(e.getKey(), t.getKey()) && eq(e.getValue(), t.getValue());
}
public String toString() {return e.toString();}
}
}
}
12.7不可变SortedMap
public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {
return new UnmodifiableSortedMap<K,V>(m);
}
static class UnmodifiableSortedMap<K,V> extends UnmodifiableMap<K,V>
implements SortedMap<K,V>, Serializable {
private static final long serialVersionUID = -8806743815996713206L;
private SortedMap<K, ? extends V> sm;
UnmodifiableSortedMap(SortedMap<K, ? extends V> m) { super(m); sm = m; }
public Comparator<? super K> comparator() { return sm.comparator(); }
public SortedMap<K,V> subMap(K fromKey, K toKey) {
return new UnmodifiableSortedMap<K,V>(sm.subMap(fromKey, toKey));
}
public SortedMap<K,V> headMap(K toKey) {
return new UnmodifiableSortedMap<K,V>(sm.headMap(toKey));
}
public SortedMap<K,V> tailMap(K fromKey) {
return new UnmodifiableSortedMap<K,V>(sm.tailMap(fromKey));
}
public K firstKey(){ return sm.firstKey(); }
public K lastKey(){ return sm.lastKey(); }
}
Collections Framework中的算法(之三)--不可变装饰器相关的更多相关文章
- python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器
1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...
- cookie,session 的概念以及在django中的用法,以及cbv装饰器用法
cookie的由来: 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后 ...
- 13、python中的函数(闭包与装饰器)
一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...
- 详解Django中六个常用的自定义装饰器
装饰器作用 decorator是当今最流行的设计模式之一,很多使用它的人并不知道它是一种设计模式.这种模式有什么特别之处? 有兴趣可以看看Python Wiki上例子,使用它可以很方便地修改对象行为, ...
- Django中六个常用的自定义装饰器
装饰器作用 decorator是当今最流行的设计模式之一,很多使用它的人并不知道它是一种设计模式.这种模式有什么特别之处? 有兴趣可以看看Python Wiki上例子,使用它可以很方便地修改对象行为, ...
- diango中的MTV——FBV/CBV以及装饰器的复用问题解决
MVC M: model 模型 与数据库交互 V: view 视图 HTML C:controller 控制器 流程 和 业务逻辑 MTV M:model ORM T:template 模板 HTML ...
- python中自带的三个装饰器
说到装饰器,就不得不说python自带的三个装饰器: 1.@property 将某函数,做为属性使用 @property 修饰,就是将方法,变成一个属性来使用. class A(): @propert ...
- Python中的迭代器、生成器、装饰器
1. 迭代器 1 """ 2 iterator 3 迭代器协议: 对象必须提供一个next()方法,执行该方法要么返回迭代中的下一项,要么引起一个StopIterati ...
- react-native 中使用redux 优化 Connect 使用装饰器简化代码报错
报错信息 error: bundling failed: Error: The 'decorators' plugin requires a 'decoratorsBeforeExport' opti ...
- Java Collections Framework
集合OR 容器 通常我们会用数组去保存一些基本数据类型,数组是编译器支持的类型,但是数组的一个明显缺点就是具有固定尺寸,而在一般情况下,只有在程序运行的时候,我们才能知道要保存的具体数目. Java类 ...
随机推荐
- Docker网络中篇-docker网络的四种类型
通过上一篇学习,我们对docker网络有了初步的了解.本篇,咱们就来实战docker网络. docker网络实战 实战docker网络,我们将从以下几个案例来讲解 1:birdge是什么? 2:hos ...
- 关于 Splay 树
前置芝士 $\LARGE {关于二叉搜索树及平衡树无聊的一大串子定义}$ 二叉搜索树(BST树) 定义 二叉搜索树是一种二叉树的树形数据结构,其定义如下: 空树是二叉搜索树. 若二叉搜索树的左子树不为 ...
- Angular Material 18+ 高级教程 – CDK Accessibility の Focus
介绍 CDK Focus 是对原生 DOM focus 的上层封装和扩展. Focus Origin 原生 DOM focus 我们只能知道 element 被 focus 了,但是无法知道它是怎么被 ...
- ASP.NET Core Library – CsvHelper
前言 平常都是用 Excel 的多, 但这一次遇到 Google Ads. 谷歌嘛, 当然不喜欢微软的 Excel. 硬是要求 CSV. 没办法, 只能找 Library 搞一搞了. 参考 Docs ...
- [The Trellor] Chapter 1
翻译软件真的翻不好,读英文小说要相信你的脑子. There's only one thing to do in Berlen - that is listening the sound of wind ...
- iOS工厂模式使用小结
一.什么是工厂方法? 正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟到子类中进行.工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好 ...
- JDK线程池详解(全网最全-原理解析、源码详解)
频繁创建新线程的缺点? 不受控风险 系统资源有限,每个人针对不同业务都可以手动创建线程,并且创建标准不一样(比如线程没有名字).当系统运行起来,所有线程都在疯狂抢占资源,毫无规则,不好管控. 另外,过 ...
- DOM 操作的常用 API 有哪些 ?
DOM 操作的常用 API 就是DOM 通过API (接口)获取页面(html)元素: 1. 节点查询 API 1.1 document.querySelector() 选择第一个匹配的元素 1.2 ...
- 理解 keep-alive
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 : 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 act ...
- 不要慌,FastGPT 告诉我这是技术性调整,利好大 A!
一觉醒来,股市又变天了,到处一片哀嚎,我看了下前几天牛市的赚钱名单,咱们公众号的粉丝没有一个在里面,说实话很失望,希望大家多做些有意义的事情,而不是整天虚度光阴.一个个平时看着都挺厉害,也没赚到钱,我 ...