zoukankan      html  css  js  c++  java
  • 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();              }

        }

     

  • 相关阅读:
    转:PHP环境搭建
    证件号码
    3、SourceTree通过PUTTY连接GitLab
    2、gitlab 新建项目
    java基础31 List集合下的Vector集合
    java基础30 List集合下的LinkedList集合
    java基础29 迭代器 listIterator() 及各种遍历集合的方法
    java基础28 单例集合Collection下的List和Set集合
    java基础27 单例集合Collection及其常用方法
    错误/异常:The project cannot be built until build path errors are resolved 和 Unbound classpath container: 'JRE System Library [JavaSE-1.7]' in project 'MyJavaCode';的解决方法
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959548.html
Copyright © 2011-2022 走看看