From dea124338ad5e81b3a481f429a9cfe3673dbe810 Mon Sep 17 00:00:00 2001 From: jellyb Date: Mon, 22 Oct 2018 14:16:30 +0800 Subject: [PATCH 1/8] reflect check --- .../src/main/java/com/iluwatar/singleton/App.java | 12 ++++++++++++ .../com/iluwatar/singleton/EnumIvoryTower.java | 15 +++++++++++++-- .../iluwatar/singleton/SingletonInterface.java | 12 ++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 singleton/src/main/java/com/iluwatar/singleton/SingletonInterface.java diff --git a/singleton/src/main/java/com/iluwatar/singleton/App.java b/singleton/src/main/java/com/iluwatar/singleton/App.java index aa40ee30047e..7de8d19e0275 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/App.java +++ b/singleton/src/main/java/com/iluwatar/singleton/App.java @@ -25,6 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Constructor; + /** * Singleton pattern ensures that the class can have only one existing instance per Java classloader * instance and provides global access to it. @@ -77,6 +79,16 @@ public static void main(String[] args) { IvoryTower ivoryTower2 = IvoryTower.getInstance(); LOGGER.info("ivoryTower1={}", ivoryTower1); LOGGER.info("ivoryTower2={}", ivoryTower2); + // reflect test singleton; + try{ + Class clazz = Class.forName("com.iluwatar.singleton.IvoryTower"); + Constructor[] cs = clazz.getDeclaredConstructors(); + cs[0].setAccessible(true); + IvoryTower IvoryTower3 = (IvoryTower)cs[0].newInstance(); + LOGGER.info("IvoryTower3={}", IvoryTower3); + }catch (Exception e){ + LOGGER.error(e.getMessage(), e); + } // lazily initialized singleton ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower1 = diff --git a/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java index e4c0b26d8b65..6600a06796c5 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/EnumIvoryTower.java @@ -28,12 +28,23 @@ * This implementation is thread safe, however adding any other method and its thread safety * is developers responsibility. */ -public enum EnumIvoryTower { +public enum EnumIvoryTower implements SingletonInterface{ - INSTANCE; + INSTANCE { + @Override + public String doSomething() { + System.err.println("*****"); + return "hello singleton"; + } + }; @Override public String toString() { return getDeclaringClass().getCanonicalName() + "@" + hashCode(); } + + public EnumIvoryTower getInstance(){ + INSTANCE.doSomething(); + return EnumIvoryTower.INSTANCE; + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/SingletonInterface.java b/singleton/src/main/java/com/iluwatar/singleton/SingletonInterface.java new file mode 100644 index 000000000000..1b77741dbdfd --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/SingletonInterface.java @@ -0,0 +1,12 @@ +package com.iluwatar.singleton; + +/** + * 描述: + * + * @author biguodong + * Create time 2018-10-17 下午8:13 + **/ +public interface SingletonInterface { + + String doSomething(); +} From c2b32fbcebe6f3ef728ceef53ef81348aee2e8d4 Mon Sep 17 00:00:00 2001 From: jellyb Date: Mon, 22 Oct 2018 18:31:04 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=8D=95=E4=BE=8B=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- singleton/pom.xml | 6 ++ .../main/java/com/iluwatar/singleton/App.java | 12 +++ .../singleton/practice/EagerlySingleton.java | 28 +++++++ .../singleton/practice/EnumSingleton.java | 22 ++++++ .../singleton/practice/LazySingleton.java | 34 +++++++++ .../LazySingletonDoubleCheckLocking.java | 49 ++++++++++++ .../practice/LazySingletonInnerClass.java | 31 ++++++++ .../singleton/practice/RegisterSingleton.java | 75 +++++++++++++++++++ .../practice/SingletonInterface.java | 12 +++ 9 files changed, 269 insertions(+) create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonDoubleCheckLocking.java create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonInnerClass.java create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/RegisterSingleton.java create mode 100644 singleton/src/main/java/com/iluwatar/singleton/practice/SingletonInterface.java diff --git a/singleton/pom.xml b/singleton/pom.xml index ac900d0a6d63..2bb08d88f56f 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -43,5 +43,11 @@ junit-jupiter-engine test + + org.springframework + spring-beans + 4.2.5.RELEASE + provided + diff --git a/singleton/src/main/java/com/iluwatar/singleton/App.java b/singleton/src/main/java/com/iluwatar/singleton/App.java index 7de8d19e0275..c35fe6676cd2 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/App.java +++ b/singleton/src/main/java/com/iluwatar/singleton/App.java @@ -95,9 +95,21 @@ public static void main(String[] args) { ThreadSafeLazyLoadedIvoryTower.getInstance(); ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower2 = ThreadSafeLazyLoadedIvoryTower.getInstance(); + LOGGER.info("threadSafeIvoryTower1={}", threadSafeIvoryTower1); LOGGER.info("threadSafeIvoryTower2={}", threadSafeIvoryTower2); + try{ + Class clazz = Class.forName("com.iluwatar.singleton.ThreadSafeLazyLoadedIvoryTower"); + Constructor[] cst = clazz.getDeclaredConstructors(); + cst[0].setAccessible(true); + ThreadSafeLazyLoadedIvoryTower threadSafeIvoryTower3 = (ThreadSafeLazyLoadedIvoryTower)cst[0].newInstance(); + LOGGER.info("threadSafeIvoryTower3={}", threadSafeIvoryTower3); + }catch (Exception e){ + LOGGER.error(e.getMessage()); + } + + // enum singleton EnumIvoryTower enumIvoryTower1 = EnumIvoryTower.INSTANCE; EnumIvoryTower enumIvoryTower2 = EnumIvoryTower.INSTANCE; diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java new file mode 100644 index 000000000000..cb1737ac4dce --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java @@ -0,0 +1,28 @@ +package com.iluwatar.singleton.practice; + + +/** + * 描述:急切的创建可以保证线程安全,静态变量在类加载的时候已经被创建 + * + * @author biguodong + * Create time 2018-10-22 下午4:17 + **/ +public final class EagerlySingleton { + + private static final EagerlySingleton instance = new EagerlySingleton(); + + /** + * 构造方法私有 + */ + private EagerlySingleton(){ + + } + + /** + * 提供访问单例的静态方法 + * @return + */ + public static EagerlySingleton getInstance(){ + return instance; + } +} diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java new file mode 100644 index 000000000000..388164626bbf --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java @@ -0,0 +1,22 @@ +package com.iluwatar.singleton.practice; + +/** + * 描述:这个实现本身是线程安全的,但是添加其他方法及线程安全性是开发人员的责任 + * + * @author biguodong + * Create time 2018-10-22 下午5:40 + **/ +public enum EnumSingleton implements SingletonInterface{ + + INSTANCE{ + @Override + public String doSomething() { + return "Hello singleton"; + } + }; + + + public static EnumSingleton getInstance(){ + return EnumSingleton.INSTANCE; + } +} diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java new file mode 100644 index 000000000000..e66de9fff594 --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java @@ -0,0 +1,34 @@ +package com.iluwatar.singleton.practice; + +/** + * 描述:线程安全的Singleton类。该实例被懒加载,因此需要同步锁机制 + * + * @author biguodong + * Create time 2018-10-22 下午4:04 + **/ +public final class LazySingleton { + private static LazySingleton instance = null; + + /** + * 构造方法私有,防止外部构建 + * 防止使用反射实例化 + */ + private LazySingleton(){ + if(instance == null){ + instance = this; + }else{ + throw new IllegalStateException("实例已存在!"); + } + } + + /** + * 只有在第一次调用实例的时才会创建,延迟加载 + * @return + */ + public static synchronized LazySingleton getInstance(){ + if(null == instance){ + return new LazySingleton(); + } + return instance; + } +} diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonDoubleCheckLocking.java b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonDoubleCheckLocking.java new file mode 100644 index 000000000000..8479fea43d61 --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonDoubleCheckLocking.java @@ -0,0 +1,49 @@ +package com.iluwatar.singleton.practice; + +/** + * 描述:懒汉模式-双重检查枷锁 + * + * @author biguodong + * Create time 2018-10-22 下午5:47 + **/ +public final class LazySingletonDoubleCheckLocking { + + private static volatile LazySingletonDoubleCheckLocking instance; + + /** + * 构造函数私有,防止外部调用 + */ + private LazySingletonDoubleCheckLocking(){ + if(null != instance){ + throw new IllegalStateException("实例已存在!"); + } + } + + public static LazySingletonDoubleCheckLocking getInstance(){ + /** + * 局部变量使性能提高25% + * Joshua Bloch "Effective Java, Second Edition", p. 283-284 + */ + LazySingletonDoubleCheckLocking result = instance; + /** + * 检查实例是否已经创建存在,如果存在,直接return + * + */ + if(result == null){ + /** + * 如果没有创建,我们不能保证同时是否有别的线程也在访问,因此,我们需要对一个对象加锁以实现互斥 + */ + synchronized (LazySingletonDoubleCheckLocking.class){ + result = instance; + if(result == null){ + /** + * 此时对象仍然为空,我们可以安全(没有其他线程可以进入此区域)创建一个实例,并使它成为我们的单例 + */ + result = instance = new LazySingletonDoubleCheckLocking(); + } + } + } + return result; + } + +} diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonInnerClass.java b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonInnerClass.java new file mode 100644 index 000000000000..4224d5a7e628 --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingletonInnerClass.java @@ -0,0 +1,31 @@ +package com.iluwatar.singleton.practice; + +/** + * 描述:线程安全的创建java单例 + * 该技术尽可能的慵懒,适用于java的所有版本,利用了关于类初始化的特征,因此可以在所有符合java规范的编译器及虚拟机中工作 + * + * 只有调用了getInstance方法,内部类才会被引用(因此类加载器不回加载),这个设计时线程安全的,不需要特殊的语言结构(synchronized, volatile) + * @author biguodong + * Create time 2018-10-22 下午6:14 + **/ +public final class LazySingletonInnerClass { + + /** + * private constructor + */ + private LazySingletonInnerClass(){ + + } + + public static LazySingletonInnerClass getInstance(){ + return HelperHolder.INSTANCE; + } + + /** + * 提供懒加载实例 + */ + private static class HelperHolder{ + private static final LazySingletonInnerClass INSTANCE = new LazySingletonInnerClass(); + + } +} diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/RegisterSingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/RegisterSingleton.java new file mode 100644 index 000000000000..c99c00d16162 --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/RegisterSingleton.java @@ -0,0 +1,75 @@ +package com.iluwatar.singleton.practice; + +import org.springframework.beans.factory.ObjectFactory; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 描述:abstractfa + * + * @author biguodong + * Create time 2018-10-22 下午4:25 + **/ +public class RegisterSingleton { + + + /** + * Internal marker for a null singleton object: + * used as marker value for concurrent Maps (which don't support null values). + */ + protected static final Object NULL_OBJECT = new Object(); + + /** Cache of singleton objects: bean name --> bean instance */ + private final Map singletonObjects = new ConcurrentHashMap(256); + + /** Cache of early singleton objects: bean name --> bean instance */ + private final Map earlySingletonObjects = new HashMap(16); + + /** Cache of singleton factories: bean name --> ObjectFactory */ + private final Map> singletonFactories = new HashMap>(16); + + + /** Names of beans that are currently in creation */ + private final Set singletonsCurrentlyInCreation = + Collections.newSetFromMap(new ConcurrentHashMap(16)); + + /** + * Return the (raw) singleton object registered under the given name. + *

Checks already instantiated singletons and also allows for an early + * reference to a currently created singleton (resolving a circular reference). + * @param beanName the name of the bean to look for + * @param allowEarlyReference whether early references should be created or not + * @return the registered singleton object, or {@code null} if none found + */ + protected Object getSingleton(String beanName, boolean allowEarlyReference) { + Object singletonObject = this.singletonObjects.get(beanName); + if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { + synchronized (this.singletonObjects) { + singletonObject = this.earlySingletonObjects.get(beanName); + if (singletonObject == null && allowEarlyReference) { + ObjectFactory singletonFactory = this.singletonFactories.get(beanName); + if (singletonFactory != null) { + singletonObject = singletonFactory.getObject(); + this.earlySingletonObjects.put(beanName, singletonObject); + this.singletonFactories.remove(beanName); + } + } + } + } + return (singletonObject != NULL_OBJECT ? singletonObject : null); + } + + /** + * Return whether the specified singleton bean is currently in creation + * (within the entire factory). + * @param beanName the name of the bean + */ + public boolean isSingletonCurrentlyInCreation(String beanName) { + return this.singletonsCurrentlyInCreation.contains(beanName); + } + +} diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/SingletonInterface.java b/singleton/src/main/java/com/iluwatar/singleton/practice/SingletonInterface.java new file mode 100644 index 000000000000..dd21e8998d28 --- /dev/null +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/SingletonInterface.java @@ -0,0 +1,12 @@ +package com.iluwatar.singleton.practice; + +/** + * 描述: + * + * @author biguodong + * Create time 2018-10-17 下午8:13 + **/ +public interface SingletonInterface { + + String doSomething(); +} From 913076422791868a77f7bfaed90d68d0785ded5d Mon Sep 17 00:00:00 2001 From: jellyb Date: Wed, 31 Oct 2018 13:35:38 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=8D=95=E4=BE=8B?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../singleton/practice/EagerlySingleton.java | 43 ++++++++++++++++-- .../singleton/practice/EnumSingleton.java | 45 +++++++++++++++++++ .../singleton/practice/LazySingleton.java | 27 +++++++++++ .../templatemethod/practice/Test.java | 21 +++++++++ 4 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java index cb1737ac4dce..27b0635a41c8 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/EagerlySingleton.java @@ -1,6 +1,12 @@ package com.iluwatar.singleton.practice; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; +import java.util.concurrent.atomic.AtomicBoolean; + /** * 描述:急切的创建可以保证线程安全,静态变量在类加载的时候已经被创建 * @@ -9,13 +15,25 @@ **/ public final class EagerlySingleton { - private static final EagerlySingleton instance = new EagerlySingleton(); + private static final Logger logger = LoggerFactory.getLogger(EagerlySingleton.class); + + /** + * 防止反射调用构造方法 + */ + private static final AtomicBoolean isInitialized = new AtomicBoolean(false); + + private static final EagerlySingleton INSTANCE = new EagerlySingleton(); /** * 构造方法私有 */ private EagerlySingleton(){ - + if(!isInitialized.get()){ + isInitialized.getAndSet(true); + }else{ + throw new IllegalStateException("实例已存在!"); + } + logger.info(">>>>>>> constructor <<<<<<<<<"); } /** @@ -23,6 +41,25 @@ private EagerlySingleton(){ * @return */ public static EagerlySingleton getInstance(){ - return instance; + return INSTANCE; + } + + public static void main(String[] args) { + + try { + EagerlySingleton eagerlySingleton1 = EagerlySingleton.getInstance(); + EagerlySingleton eagerlySingleton2 = EagerlySingleton.getInstance(); + logger.info("EagerlySingleton:{}", eagerlySingleton1); + logger.info("EagerlySingleton:{}", eagerlySingleton2); + + Class clazz = Class.forName("com.iluwatar.singleton.practice.EagerlySingleton"); + Constructor[] cst = clazz.getDeclaredConstructors(); + cst[0].setAccessible(true); + EagerlySingleton eagerlySingleton3 = (EagerlySingleton) cst[0].newInstance(); + logger.info("EagerlySingleton:{}", eagerlySingleton3); + }catch (Exception e){ + logger.error(e.getMessage(), e); + } + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java index 388164626bbf..3bfe59b955c3 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/EnumSingleton.java @@ -1,5 +1,11 @@ package com.iluwatar.singleton.practice; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; + /** * 描述:这个实现本身是线程安全的,但是添加其他方法及线程安全性是开发人员的责任 * @@ -8,15 +14,54 @@ **/ public enum EnumSingleton implements SingletonInterface{ + INSTANCE{ + Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public String doSomething() { + logger.info("do something"); return "Hello singleton"; } + + + /** + * Returns the name of this enum constant, as contained in the + * declaration. This method may be overridden, though it typically + * isn't necessary or desirable. An enum type should override this + * method when a more "programmer-friendly" string form exists. + * + * @return the name of this enum constant + */ + @Override + public String toString() { + return getDeclaringClass().getCanonicalName() + "@" + hashCode(); + } + }; + public static EnumSingleton getInstance(){ return EnumSingleton.INSTANCE; } + + public static void main(String[] args) { + try{ + EnumSingleton enumSingleton1 = EnumSingleton.getInstance(); + EnumSingleton enumSingleton2 = EnumSingleton.getInstance(); + System.out.println(String.format("EnumSingleton:%s", enumSingleton1.toString())); + System.out.println(String.format("EnumSingleton:%s", enumSingleton2.toString())); + + Class clazz = Class.forName("com.iluwatar.singleton.practice.EnumSingleton"); + Constructor[] cst = clazz.getDeclaredConstructors(); + cst[0].setAccessible(true); + EnumSingleton enumSingleton3 = (EnumSingleton)cst[0].newInstance(); + System.out.println(String.format("EnumSingleton:%s", enumSingleton3.toString())); + }catch (Exception e){ + System.err.println(e.getMessage()); + } + + + + } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java index e66de9fff594..ad5cc8cc976f 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java +++ b/singleton/src/main/java/com/iluwatar/singleton/practice/LazySingleton.java @@ -1,5 +1,10 @@ package com.iluwatar.singleton.practice; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Constructor; + /** * 描述:线程安全的Singleton类。该实例被懒加载,因此需要同步锁机制 * @@ -7,6 +12,7 @@ * Create time 2018-10-22 下午4:04 **/ public final class LazySingleton { + private static Logger logger = LoggerFactory.getLogger(LazySingleton.class); private static LazySingleton instance = null; /** @@ -31,4 +37,25 @@ public static synchronized LazySingleton getInstance(){ } return instance; } + + public static void main(String[] args) { + /** + * LazySingleton + */ + try{ + LazySingleton lazySingleton1 = LazySingleton.getInstance(); + LazySingleton lazySingleton2 = LazySingleton.getInstance(); + logger.info("LazySingleton:{}", lazySingleton1); + logger.info("LazySingleton:{}", lazySingleton2); + Class clazz = Class.forName("com.iluwatar.singleton.practice.LazySingleton"); + Constructor[] cst = clazz.getDeclaredConstructors(); + cst[0].setAccessible(true); + LazySingleton lazySingleton3 = (LazySingleton)cst[0].newInstance(); + logger.info("LazySingleton:{}", lazySingleton3); + }catch (Exception e){ + logger.error(e.getMessage(), e); + } + + + } } diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java new file mode 100644 index 000000000000..7daba7f9c516 --- /dev/null +++ b/template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java @@ -0,0 +1,21 @@ +package com.iluwatar.templatemethod.practice; + +import java.util.Arrays; + +/** + * 描述: + * + * @author biguodong + * Create time 2018-10-31 上午10:35 + **/ +public class Test { + + public static void main(String[] args) { + int[] array = new int[]{1, 2, 2, 2, 3, 3, 3, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + int oneSize = Arrays.stream(array).filter(item-> item == 1).map(item -> 1).reduce(0, Integer::sum); + int twoSize = Arrays.stream(array).filter(item-> item == 2).map(item -> 1).reduce(0, Integer::sum); + int threeSize = Arrays.stream(array).filter(item-> item == 3).map(item -> 1).reduce(0, Integer::sum); + System.err.println("one:" + oneSize + " two:" + twoSize + " three:" + threeSize); + System.err.println(array.length); + } +} From 39440bf903fcfcf67a4f3cf1df62708f846df0b8 Mon Sep 17 00:00:00 2001 From: jellyb Date: Wed, 31 Oct 2018 17:45:40 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E5=B0=8F=E5=81=B7-=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practice/AbstractStealingMethod.java | 48 +++++++++++++++++++ .../iluwatar/templatemethod/practice/App.java | 20 ++++++++ .../templatemethod/practice/HalfingThief.java | 24 ++++++++++ .../practice/HitAndRunStealingMethod.java | 45 +++++++++++++++++ .../practice/SubtleStealingMethod.java | 44 +++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/AbstractStealingMethod.java create mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/App.java create mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/HalfingThief.java create mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/HitAndRunStealingMethod.java create mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/SubtleStealingMethod.java diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/AbstractStealingMethod.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/AbstractStealingMethod.java new file mode 100644 index 000000000000..2a9d54338580 --- /dev/null +++ b/template-method/src/main/java/com/iluwatar/templatemethod/practice/AbstractStealingMethod.java @@ -0,0 +1,48 @@ +package com.iluwatar.templatemethod.practice; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 描述: 抽象模板类 + * + * @author biguodong + * Create time 2018-10-31 下午4:18 + **/ +public abstract class AbstractStealingMethod { + + private static final Logger logger = LoggerFactory.getLogger(AbstractStealingMethod.class); + + /** + * 挑选目标 + * @return + */ + protected abstract String pickedTarget(); + + /** + * 迷惑目标 + * @param target + */ + protected abstract void confusedTarget(String target); + + + /** + * 偷取 + * @param target + */ + protected abstract void stealTheItem(String target); + + /** + * 模板方法 + * 执行顺序 + * 1. 挑选目标 + * 2. 迷惑目标 + * 3. 偷取目标 + */ + public final void steal(){ + String target = pickedTarget(); + logger.info("选中目标 {}.", target); + confusedTarget(target); + stealTheItem(target); + } +} diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/App.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/App.java new file mode 100644 index 000000000000..aabdfbcda0b1 --- /dev/null +++ b/template-method/src/main/java/com/iluwatar/templatemethod/practice/App.java @@ -0,0 +1,20 @@ +package com.iluwatar.templatemethod.practice; + +/** + * 描述:模板方法使用类定义骨架,子类为空白部分提供实现。 + * + * @author biguodong + * Create time 2018-10-31 下午4:49 + **/ +public class App { + + public static void main(String[] args) { + HalfingThief halfingThief = new HalfingThief(new HitAndRunStealingMethod()); + + halfingThief.steal(); + + halfingThief.changeMethod(new SubtleStealingMethod()); + + halfingThief.steal(); + } +} diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/HalfingThief.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/HalfingThief.java new file mode 100644 index 000000000000..765136430edb --- /dev/null +++ b/template-method/src/main/java/com/iluwatar/templatemethod/practice/HalfingThief.java @@ -0,0 +1,24 @@ +package com.iluwatar.templatemethod.practice; + +/** + * 描述:半身人小偷使用 {@link AbstractStealingMethod} 偷东西 + * + * @author biguodong + * Create time 2018-10-31 下午4:26 + **/ +public class HalfingThief { + + private AbstractStealingMethod stealingMethod; + + public HalfingThief(AbstractStealingMethod stealingMethod) { + this.stealingMethod = stealingMethod; + } + + public void steal(){ + stealingMethod.steal(); + } + + public void changeMethod(AbstractStealingMethod method){ + this.stealingMethod = method; + } +} diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/HitAndRunStealingMethod.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/HitAndRunStealingMethod.java new file mode 100644 index 000000000000..3a9f7ad61254 --- /dev/null +++ b/template-method/src/main/java/com/iluwatar/templatemethod/practice/HitAndRunStealingMethod.java @@ -0,0 +1,45 @@ +package com.iluwatar.templatemethod.practice; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 描述: 直接干偷取方法 实现 of {@link AbstractStealingMethod} + * + * @author biguodong + * Create time 2018-10-31 下午4:25 + **/ +public class HitAndRunStealingMethod extends AbstractStealingMethod{ + + private static final Logger logger = LoggerFactory.getLogger(HitAndRunStealingMethod.class); + + /** + * 挑选目标 + * + * @return + */ + @Override + protected String pickedTarget() { + return "老妖精女人"; + } + + /** + * 迷惑目标 + * + * @param target + */ + @Override + protected void confusedTarget(String target) { + logger.info("从后面悄悄靠近{}", target); + } + + /** + * 窃取商品 + * + * @param target + */ + @Override + protected void stealTheItem(String target) { + logger.info("拿起手提包快速逃跑~"); + } +} diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/SubtleStealingMethod.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/SubtleStealingMethod.java new file mode 100644 index 000000000000..1f5d88ca8c43 --- /dev/null +++ b/template-method/src/main/java/com/iluwatar/templatemethod/practice/SubtleStealingMethod.java @@ -0,0 +1,44 @@ +package com.iluwatar.templatemethod.practice; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 描述:微妙的偷取方法 实现 of {@link AbstractStealingMethod} + * + * @author biguodong + * Create time 2018-10-31 下午4:23 + **/ +public class SubtleStealingMethod extends AbstractStealingMethod{ + + private static final Logger logger = LoggerFactory.getLogger(SubtleStealingMethod.class); + /** + * 挑选目标 + * + * @return + */ + @Override + protected String pickedTarget() { + return "商店老板"; + } + + /** + * 迷惑目标 + * + * @param target + */ + @Override + protected void confusedTarget(String target) { + logger.info("泪牛满面的接近{},并抱住他", target); + } + + /** + * 窃取商品 + * + * @param target + */ + @Override + protected void stealTheItem(String target) { + logger.info("在靠近的同时悄悄摸取{}的钱包~", target); + } +} From 20fb9013daeb02cced7e141a48359603c1cbcbf3 Mon Sep 17 00:00:00 2001 From: jellyb Date: Wed, 31 Oct 2018 17:47:50 +0800 Subject: [PATCH 5/8] update --- .../templatemethod/practice/Test.java | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java b/template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java deleted file mode 100644 index 7daba7f9c516..000000000000 --- a/template-method/src/main/java/com/iluwatar/templatemethod/practice/Test.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.iluwatar.templatemethod.practice; - -import java.util.Arrays; - -/** - * 描述: - * - * @author biguodong - * Create time 2018-10-31 上午10:35 - **/ -public class Test { - - public static void main(String[] args) { - int[] array = new int[]{1, 2, 2, 2, 3, 3, 3, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; - int oneSize = Arrays.stream(array).filter(item-> item == 1).map(item -> 1).reduce(0, Integer::sum); - int twoSize = Arrays.stream(array).filter(item-> item == 2).map(item -> 1).reduce(0, Integer::sum); - int threeSize = Arrays.stream(array).filter(item-> item == 3).map(item -> 1).reduce(0, Integer::sum); - System.err.println("one:" + oneSize + " two:" + twoSize + " three:" + threeSize); - System.err.println(array.length); - } -} From c649627b12d5ff298c614f3b832be6ef634c6195 Mon Sep 17 00:00:00 2001 From: jellyb Date: Sat, 15 Dec 2018 11:32:22 +0800 Subject: [PATCH 6/8] guava cache --- caching/pom.xml | 6 +++ .../caching/practice/GuavaCacheTest.java | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 caching/src/test/java/com/iluwatar/caching/practice/GuavaCacheTest.java diff --git a/caching/pom.xml b/caching/pom.xml index f86f8b2bab2f..79f253dff8a9 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -58,6 +58,12 @@ bson 3.0.4 + + com.google.guava + guava + 19.0 + test +