├── .gitignore ├── .idea ├── misc.xml └── modules.xml ├── README.md ├── common └── src │ ├── algo │ ├── BubbleSort.java │ ├── IpAddress.java │ ├── MergeSort.java │ └── QuickSort.java │ ├── classloader │ ├── FileSystemClassLoader.java │ ├── HelloClassLoader.java │ ├── LocalClassCopy.java │ ├── MusicPlayer2.java │ ├── NetworkClassCopy.java │ └── NetworkClassLoader.java │ └── java │ └── lang │ └── String.java ├── data-structure └── src │ ├── HelloList.java │ ├── algo │ ├── sort │ │ ├── MergeSort.java │ │ └── QuickSort.java │ └── tree │ │ ├── MinHeap.java │ │ ├── OrderSearch.java │ │ └── TreeNode.java │ ├── annotation │ ├── compile │ │ ├── Generator.java │ │ ├── HelloCompileAnnotation.java │ │ └── UserBean.java │ └── runtime │ │ ├── Alias.java │ │ ├── HelloRuntimeAnnotation.java │ │ ├── Test.java │ │ └── UserBean.java │ └── reflection │ ├── Calculator.java │ ├── ForArticle.java │ ├── HelloReflection.java │ └── Invoke.java ├── design-pattern └── src │ ├── HelloBuilder.java │ ├── proxy │ ├── ISecondSubject.java │ ├── ISubject.java │ ├── MethodTimingProxy.java │ ├── ProxyTest.java │ ├── RealSubject.java │ └── httpRecorder │ │ ├── HttpLoggerProxy.java │ │ ├── IHandler.java │ │ └── RequestHandler.java │ └── singleton │ ├── BadSingleInstance.java │ ├── HelloSingleInstance.java │ ├── SingleElvis.java │ ├── SingleEnum.java │ ├── SingleJay.java │ └── Singleton.java ├── effective-java └── src │ └── equals_hashcode │ ├── HelloEqualsHashcode.java │ ├── PhoneNumber.java │ └── PhoneNumberWithoutHashcode.java ├── multi-thread └── src │ ├── ForArticle.java │ ├── HelloConcurrent.java │ ├── HelloProducerConsumer.java │ ├── HelloThreadLocal.java │ ├── HelloVolatile.java │ └── Test.java └── proxy └── $Proxy0.class /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/workspace.xml 2 | 3 | 4 | .idea/* 5 | *.iml 6 | out/ 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HelloJava 2 | Java basic learning 3 | -------------------------------------------------------------------------------- /common/src/algo/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package algo; 2 | 3 | /** 4 | * 先遍历一遍找到最大值的index,换到最后 5 | * 递归 6 | */ 7 | public class BubbleSort { 8 | public static void main(String[] args) { 9 | int input[] = {100, 5, 4, 3, 2, 1, 9, 3, 2, 200}; 10 | bubbleSort(input); 11 | for (int i=0; i input[maxIndex]) { 26 | maxIndex = start; 27 | } 28 | } 29 | if (input[maxIndex] > input[end]) { 30 | int temp = input[end]; 31 | input[end] = input[maxIndex]; 32 | input[maxIndex] = temp; 33 | } 34 | _bubbleSort(input, end - 1); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/src/algo/IpAddress.java: -------------------------------------------------------------------------------- 1 | package algo; 2 | 3 | /** 4 | * IP String -> 32 int 5 | */ 6 | public class IpAddress { 7 | 8 | public static void main(String[] args) { 9 | unitTest(); 10 | } 11 | 12 | /** 13 | * Calculate (input * (256^time)) by bit shifting 14 | */ 15 | private static long _pow(int input, int time) { 16 | long result = input; 17 | while (time > 0) { 18 | result <<= 8; 19 | time--; 20 | } 21 | return result; 22 | } 23 | 24 | private static long calculateIpAddress(String ipAddress) { 25 | int pow = 0; // 256^_pow 26 | int tenPow = 0; // 10^tenPow 27 | int currentNumber = 0; 28 | long result = 0; 29 | 30 | for (int i=ipAddress.length() - 1; i >= -1; i--) { 31 | char value; 32 | if (i == -1) { 33 | value = '.'; 34 | } else { 35 | value = ipAddress.charAt(i); 36 | } 37 | if ('0' <= value && value <= '9') { 38 | currentNumber += (value - '0') * (Math.pow(10, tenPow)); 39 | tenPow++; 40 | } else if ('.' == value){ 41 | if (currentNumber > 255) { 42 | throw new IllegalArgumentException("Each field must be less than 256. Invalid input: " + ipAddress); 43 | } 44 | 45 | result += _pow(currentNumber, pow); 46 | pow++; 47 | tenPow = 0; 48 | currentNumber = 0; 49 | } else if (' ' == value && tenPow != 0 && i >= 1) { 50 | char nextValueMustBeSpaceOrDot = ipAddress.charAt(i - 1); 51 | 52 | if('0' <= nextValueMustBeSpaceOrDot && nextValueMustBeSpaceOrDot <= '9') { 53 | throw new IllegalArgumentException("No space is allowed between digit. Invalid input: " + ipAddress); 54 | } 55 | } 56 | } 57 | 58 | return result; 59 | } 60 | 61 | private static void unitTest() { 62 | String[] ipList = {"0.0.0.0", "192.168.50.10", " 192 . 168 . 50 . 10 ", "192.16 8.50.10", "192.168.50.1 0", "192.168.255.10", "192.168.256.10", "256.168.255.10"}; 63 | String[] resultList = {"0", "3232248330", "3232248330", "reportError", "reportError", "3232300810", "reportError", "reportError"}; 64 | for (int i=0; i intput[j]) { 34 | int temp = intput[j]; 35 | for (int tempIndex = j; tempIndex > i; tempIndex--) { 36 | intput[tempIndex] = intput[tempIndex - 1]; 37 | } 38 | intput[i++] = temp; 39 | j++; 40 | middle++; //注意,middle应该时刻指向左数组的最大值,当整体右移时,该index也要随着移动 41 | } else { 42 | i++; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/src/algo/QuickSort.java: -------------------------------------------------------------------------------- 1 | package algo; 2 | 3 | /** 4 | * 先排好最后一个数的位置 5 | * 递归 6 | */ 7 | public class QuickSort { 8 | 9 | public static void main(String[] args) { 10 | int input[] = {5, 4, 3, 2, 1, 9, 3, 2}; 11 | quickSort(input); 12 | for (int i=0; i findClass(String name) throws ClassNotFoundException { 12 | byte[] classData = loadClassDataFromFile(name); 13 | if (classData == null) { 14 | return super.findClass(name); 15 | } else { 16 | return defineClass(name, classData, 0, classData.length); 17 | } 18 | } 19 | 20 | private byte[] loadClassDataFromFile(String name) { 21 | String localPath = "/Users/Jay" + File.separatorChar + "Desktop" + File.separatorChar + name.replace('.', File.separatorChar) + ".class"; 22 | System.out.printf("localPath: %s\n", localPath); 23 | 24 | try { 25 | InputStream inputStream = new FileInputStream(localPath); 26 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 27 | int bufferSize = 4096; 28 | byte[] buffer = new byte[bufferSize]; // 4KB 29 | int bytesNumRead = 0; 30 | while ((bytesNumRead = inputStream.read(buffer)) != -1) { 31 | System.out.printf("bytesNumRead: %s bytes\n", bytesNumRead); 32 | byteArrayOutputStream.write(buffer, 0, bytesNumRead); 33 | } 34 | return byteArrayOutputStream.toByteArray(); 35 | } catch (FileNotFoundException e) { 36 | e.printStackTrace(); 37 | } catch (IOException e) { 38 | e.printStackTrace(); 39 | } 40 | 41 | return null; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /common/src/classloader/HelloClassLoader.java: -------------------------------------------------------------------------------- 1 | package classloader; 2 | 3 | 4 | import sun.misc.Launcher; 5 | import sun.reflect.CallerSensitive; 6 | import sun.reflect.Reflection; 7 | 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.InvocationTargetException; 10 | import java.lang.reflect.Method; 11 | import java.net.URL; 12 | 13 | /** 14 | * Created by Jay on 5/4/17. 15 | */ 16 | public class HelloClassLoader { 17 | 18 | public static void main(String[] args) throws ClassNotFoundException { 19 | // URL[] urls = Launcher.getBootstrapClassPath().getURLs(); 20 | // for (int i = 0; i < urls.length; i++) { 21 | // System.out.println(urls[i].toExternalForm()); 22 | // } 23 | 24 | // loadExtLibClass(); 25 | // loadClass(); 26 | // mock String class 27 | // mockStringClass(); 28 | 29 | // fileSystemClassLoader, load ~/Desktop/LocalClassCopy , print() 30 | // loadFileSystemClass(); 31 | // different classloader will load different class 32 | // loadClassByDifferentLoader(); 33 | 34 | // load Network class. load http://localhost/java/classloader/NetworkClass.class, it's under /Library/WebServer/Documents directory 35 | loadNetworkClass(); 36 | } 37 | 38 | private static void loadNetworkClass() throws ClassNotFoundException { 39 | String className = "classloader.NetworkClass"; 40 | NetworkClassLoader networkClassLoader = new NetworkClassLoader(); 41 | Class clazz = networkClassLoader.loadClass(className); 42 | 43 | Method printMethod = null; 44 | try { 45 | printMethod = clazz.getDeclaredMethod("print", null); 46 | printMethod.invoke(clazz.newInstance()); 47 | } catch (NoSuchMethodException e) { 48 | e.printStackTrace(); 49 | } catch (IllegalAccessException e) { 50 | e.printStackTrace(); 51 | } catch (InstantiationException e) { 52 | e.printStackTrace(); 53 | } catch (InvocationTargetException e) { 54 | e.printStackTrace(); 55 | } 56 | 57 | } 58 | 59 | private static void loadFileSystemClass() throws ClassNotFoundException { 60 | String className = "classloader.LocalClassCopy"; 61 | FileSystemClassLoader fileSystemClassLoader = new FileSystemClassLoader(); 62 | Class clazz = fileSystemClassLoader.loadClass(className); 63 | 64 | try { 65 | Method printMethod = clazz.getDeclaredMethod("print", null); 66 | printMethod.invoke(clazz.newInstance(), null); 67 | } catch (NoSuchMethodException e) { 68 | e.printStackTrace(); 69 | } catch (IllegalAccessException e) { 70 | e.printStackTrace(); 71 | } catch (InstantiationException e) { 72 | e.printStackTrace(); 73 | } catch (InvocationTargetException e) { 74 | e.printStackTrace(); 75 | } 76 | } 77 | 78 | private static void loadClassByDifferentLoader() throws ClassNotFoundException { 79 | FileSystemClassLoader classLoader1 = new FileSystemClassLoader(); 80 | FileSystemClassLoader classLoader2 = new FileSystemClassLoader(); 81 | 82 | Class clazz1 = classLoader1.loadClass("classloader.LocalClass"); 83 | Class clazz2 = classLoader2.loadClass("classloader.LocalClass"); 84 | 85 | // System.out.println(ClassLoader.getSystemClassLoader()); // AppClassLoader 86 | System.out.println(clazz1.getClassLoader()); // FileSystemClassLoader 87 | System.out.println(clazz2.getClassLoader()); // FileSystemClassLoader 88 | 89 | try { 90 | Object object1 = clazz1.newInstance(); 91 | Method printMethod = clazz1.getDeclaredMethod("print", null); 92 | printMethod.invoke(object1); 93 | 94 | Method setInstanceMethod = clazz1.getMethod("setInstance", Object.class); 95 | Object object2 = clazz2.newInstance(); 96 | setInstanceMethod.invoke(object1, object2); 97 | } catch (InstantiationException e) { 98 | e.printStackTrace(); 99 | } catch (IllegalAccessException e) { 100 | e.printStackTrace(); 101 | } catch (NoSuchMethodException e) { 102 | e.printStackTrace(); 103 | } catch (InvocationTargetException e) { 104 | e.printStackTrace(); 105 | } 106 | } 107 | 108 | private static void mockStringClass() throws ClassNotFoundException { 109 | Class stringClass = Class.forName("java.lang.String"); 110 | try { 111 | Method printNameMethod = stringClass.getMethod("printName", null); // NoSuchMethodException 112 | System.out.printf("printNameMethod = %s", (printNameMethod == null)); 113 | } catch (NoSuchMethodException e) { 114 | e.printStackTrace(); 115 | } 116 | } 117 | 118 | private static void loadClass() throws ClassNotFoundException { 119 | ClassLoader appClassLoader = ClassLoader.getSystemClassLoader(); 120 | Class clazz1 = appClassLoader.loadClass("classloader.MusicPlayer"); 121 | System.out.println(clazz1.getClassLoader()); 122 | 123 | Class clazz2 = Class.forName("classloader.MusicPlayer2"); 124 | ClassLoader classLoader = clazz2.getClassLoader(); 125 | System.out.println(classLoader); 126 | 127 | Class clazz3 = Class.forName("java.lang.String"); 128 | System.out.println(clazz3.getClassLoader()); 129 | 130 | Class clazz4 = new NetworkClassLoader().loadClass("java.lang.String"); 131 | System.out.println(clazz4.getClassLoader()); 132 | } 133 | 134 | private static void loadExtLibClass() { 135 | // mv MusicPlayer.jar into jre/lib/ext/ 136 | ClassLoader classLoader = new NetworkClassLoader(); 137 | classLoader = classLoader.getParent().getParent(); // ExtClassLoader 138 | System.out.println(classLoader); 139 | try { 140 | classLoader.loadClass("classloader.MusicPlayer"); // this is in jre/lib/ext/ 141 | classLoader.loadClass("classloader.MusicPlayer2"); 142 | } catch (ClassNotFoundException e) { 143 | e.printStackTrace(); 144 | } 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /common/src/classloader/LocalClassCopy.java: -------------------------------------------------------------------------------- 1 | package classloader; 2 | 3 | /** 4 | * LocalClassCopy will be loaded by FileSystemClassLoader 5 | */ 6 | public class LocalClassCopy { 7 | 8 | public void print() { 9 | System.out.println("Hi Here is LocalClassCopy"); 10 | } 11 | 12 | private LocalClassCopy instance; 13 | public void setInstance(Object instance) { 14 | this.instance = (LocalClassCopy) instance; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /common/src/classloader/MusicPlayer2.java: -------------------------------------------------------------------------------- 1 | package classloader; 2 | 3 | /** 4 | * Created by Jay on 5/4/17. 5 | */ 6 | public class MusicPlayer2 { 7 | 8 | public void start() { 9 | System.out.printf("start Play Music"); 10 | } 11 | 12 | public void end() { 13 | System.out.printf("end play music"); 14 | } 15 | 16 | private MusicPlayer2 instance; 17 | public void setMusicPlayer2(Object musicPlayer2) { 18 | this.instance = (MusicPlayer2) musicPlayer2; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /common/src/classloader/NetworkClassCopy.java: -------------------------------------------------------------------------------- 1 | package classloader; 2 | 3 | /** 4 | * NetworkClassCopy will be loaded by NetworkClassLoader 5 | */ 6 | public class NetworkClassCopy { 7 | 8 | public void print() { 9 | System.out.println("Hi Here is networkClass"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /common/src/classloader/NetworkClassLoader.java: -------------------------------------------------------------------------------- 1 | package classloader; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.InputStream; 6 | import java.net.URL; 7 | 8 | /** 9 | * Load class from network 10 | */ 11 | public class NetworkClassLoader extends ClassLoader { 12 | 13 | @Override 14 | protected Class findClass(String name) throws ClassNotFoundException { 15 | byte[] classData = downloadClassData(name); 16 | if (classData == null) { 17 | super.findClass(name); 18 | } else { 19 | return defineClass(name, classData, 0, classData.length); 20 | } 21 | return null; 22 | } 23 | 24 | private byte[] downloadClassData(String name) { 25 | String path = "http://localhost" + File.separatorChar + "java" + File.separatorChar + name.replace('.', File.separatorChar) + ".class"; 26 | System.out.printf("localPath: %s\n", path); 27 | 28 | try { 29 | URL url = new URL(path); 30 | InputStream ins = url.openStream(); 31 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 32 | int bufferSize = 4096; 33 | byte[] buffer = new byte[bufferSize]; 34 | int bytesNumRead = 0; 35 | while ((bytesNumRead = ins.read(buffer)) != -1) { 36 | baos.write(buffer, 0, bytesNumRead); 37 | } 38 | return baos.toByteArray(); 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | return null; 43 | } 44 | 45 | public String getName() { 46 | System.out.printf("Real NetworkClassLoader\n"); 47 | return "networkClassLoader"; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /common/src/java/lang/String.java: -------------------------------------------------------------------------------- 1 | package java.lang; 2 | 3 | /** 4 | * Created by Jay on 5/8/17. 5 | */ 6 | public class String { 7 | 8 | public void printName() { 9 | System.out.println("I'm mock String"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /data-structure/src/HelloList.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.LinkedList; 3 | import java.util.List; 4 | import java.util.Random; 5 | 6 | /** 7 | * Created by Jay on 4/17/17. 8 | */ 9 | public class HelloList { 10 | 11 | public static void main(String[] args) { 12 | // ArrayList, LinkedList, Vector 13 | // CopyOnWriteList 14 | 15 | //1. ArrayList 查询比 LinkedList 快 16 | // querySpeed(); 17 | 18 | //2. LinkedList 比 ArrayList 插入快 19 | // insertSpeed(); 20 | 21 | //3. LinkedList 比 ArrayList 删除快 22 | // removeSpeed(); 23 | 24 | } 25 | 26 | private static void querySpeed() { 27 | ArrayList arrayList = new ArrayList<>(); 28 | LinkedList linkedList = new LinkedList<>(); 29 | 30 | int size = 50000; 31 | for (int i=0; i=0; j--) { 38 | arrayList.get(j); 39 | } 40 | System.out.println("Query ArrayList needs time: " + (System.currentTimeMillis() - start)); 41 | 42 | start = System.currentTimeMillis(); 43 | for (int j=size-1; j>=0; j--) { 44 | linkedList.get(j); 45 | } 46 | System.out.println("Query LinkedList needs time: " + (System.currentTimeMillis() - start)); 47 | } 48 | 49 | private static void insertSpeed() { 50 | int size = 100000; 51 | ArrayList arrayList = new ArrayList<>(); 52 | LinkedList linkedList = new LinkedList<>(); 53 | 54 | long start = System.currentTimeMillis(); 55 | for (int i=0; i arrayList = new ArrayList<>(); 69 | LinkedList linkedList = new LinkedList<>(); 70 | 71 | int size = 50000; 72 | for (int i=0; i每四个归并->每八个归并 12 | */ 13 | public class MergeSort { 14 | 15 | public static void main(String[] args) { 16 | // int[] nums = {3, 2, 4, 1, 5}; 17 | // recursionSort(nums); 18 | 19 | List result = new ArrayList<>(); 20 | int a = 'a'; 21 | System.out.println(String.valueOf(a)); 22 | int[] num = {1, 1, 2, 2, 3, 2}; 23 | System.out.println(majorityElement(num)); 24 | } 25 | private static int majorityElement(int[] num) { 26 | Arrays.sort(num); 27 | int major=num[0], count = 1; 28 | for(int i=1; i mid && j <= end) { 63 | while (j <= end) temp[index++] = nums[j++]; 64 | } 65 | if (i <= mid && j > end) { 66 | while (i <= mid) temp[index++] = nums[i++]; 67 | } 68 | for(i=start, index=0; i <= end; ) nums[i++] = temp[index++]; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /data-structure/src/algo/sort/QuickSort.java: -------------------------------------------------------------------------------- 1 | package algo.sort; 2 | 3 | /** 4 | * Created by wingjay on 08/03/2018. 5 | */ 6 | public class QuickSort { 7 | //以最右为基准,遍历,小的放左边,大的放右边,然后分治 8 | 9 | public static void main(String[] args) { 10 | int[] case1 = {5, 8, 11,2,13,4}; 11 | sort(case1); 12 | for (int i = 0; i < case1.length; i++) { 13 | System.out.println(case1[i]); 14 | } 15 | } 16 | 17 | private static void sort(int[] nums) { 18 | sort(nums, 0, nums.length-1); 19 | } 20 | 21 | private static void sort(int[] nums, int start, int end) { 22 | if (start >= end) return; 23 | int storeIndex = start; 24 | int pivot = nums[end]; 25 | for (int i=start; i把左节点押入栈->继续打印左节点至null->从栈弹出上一个左节点->指向其右节点 ] 22 | // https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 23 | public List preOrderTraversal(TreeNode root) { 24 | List result = new ArrayList<>(); 25 | Stack stack = new Stack<>(); 26 | TreeNode cur = root; 27 | while (cur != null || !stack.empty()) { 28 | while (cur != null) { 29 | result.add(cur.val); 30 | stack.push(cur); 31 | cur = cur.left; 32 | } 33 | cur = stack.pop(); 34 | cur = cur.right; 35 | } 36 | return result; 37 | } 38 | 39 | // 后序 40 | public List postOrderTraversal(TreeNode root) { 41 | List result = new ArrayList<>(); 42 | Stack stack = new Stack<>(); 43 | TreeNode cur = root; 44 | 45 | while (cur != null || !stack.empty()) { 46 | while (cur != null) { 47 | stack.push(cur); 48 | cur = cur.left; 49 | } 50 | cur = stack.pop(); 51 | if (cur.right != null) { 52 | stack.push(cur); 53 | cur = cur.right; 54 | } else { 55 | result.add(cur.val); 56 | } 57 | } 58 | return result; 59 | } 60 | 61 | // 中序遍历:一直把左节点压进栈,然后逐个弹出来,打印自身及右节点 62 | // https://leetcode.com/problems/binary-tree-inorder-traversal/description/ 63 | public List inorderTraversal(TreeNode root) { 64 | List result = new ArrayList<>(); 65 | Stack stack = new Stack<>(); 66 | TreeNode cur = root; 67 | while(cur != null || !stack.empty()) { 68 | while (cur != null) { 69 | stack.push(cur); 70 | cur = cur.left; 71 | } 72 | cur = stack.pop(); 73 | result.add(cur.val); 74 | cur = cur.right; 75 | } 76 | return result; 77 | } 78 | 79 | public static void main(String[] args) { 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /data-structure/src/algo/tree/TreeNode.java: -------------------------------------------------------------------------------- 1 | package algo.tree; 2 | 3 | /** 4 | * Created by wingjay on 07/03/2018. 5 | */ 6 | public class TreeNode { 7 | int val; 8 | TreeNode left; 9 | TreeNode right; 10 | TreeNode(int x) { val = x; } 11 | } 12 | -------------------------------------------------------------------------------- /data-structure/src/annotation/compile/Generator.java: -------------------------------------------------------------------------------- 1 | package annotation.compile; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by Jay on 5/3/17. 10 | */ 11 | @Retention(RetentionPolicy.CLASS) 12 | @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.TYPE, ElementType.METHOD}) 13 | public @interface Generator { 14 | } 15 | -------------------------------------------------------------------------------- /data-structure/src/annotation/compile/HelloCompileAnnotation.java: -------------------------------------------------------------------------------- 1 | package annotation.compile; 2 | 3 | /** 4 | * Created by Jay on 5/3/17. 5 | */ 6 | public class HelloCompileAnnotation { 7 | 8 | public static void main(String[] args) { 9 | UserBean userBean = new UserBean(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /data-structure/src/annotation/compile/UserBean.java: -------------------------------------------------------------------------------- 1 | package annotation.compile; 2 | 3 | /** 4 | * Created by Jay on 5/3/17. 5 | */ 6 | @Generator 7 | public class UserBean { 8 | 9 | @Generator 10 | String userName; 11 | 12 | @Generator 13 | public String getUserName() { 14 | return userName; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /data-structure/src/annotation/runtime/Alias.java: -------------------------------------------------------------------------------- 1 | package annotation.runtime; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.FIELD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface Alias { 11 | String value(); 12 | } 13 | -------------------------------------------------------------------------------- /data-structure/src/annotation/runtime/HelloRuntimeAnnotation.java: -------------------------------------------------------------------------------- 1 | package annotation.runtime; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Modifier; 6 | import java.util.HashMap; 7 | 8 | /** 9 | * Created by Jay on 4/21/17. 10 | */ 11 | public class HelloRuntimeAnnotation { 12 | 13 | public static void main(String[] args) { 14 | UserBean userBean = new UserBean("Jay", 100); 15 | // printAlias(userBean); 16 | // System.out.println(objectToMap(userBean)); 17 | // 18 | doTest(userBean); 19 | } 20 | 21 | /** 22 | * print alias during runtime 23 | */ 24 | private static void printAlias(Object userBeanObject) { 25 | for (Field field : userBeanObject.getClass().getDeclaredFields()) { 26 | if (field.isAnnotationPresent(Alias.class)) { 27 | Alias alias = field.getAnnotation(Alias.class); 28 | System.out.println(alias.value()); 29 | } 30 | } 31 | } 32 | 33 | /** 34 | * Convert Object to HashMap, key is Annotation value 35 | */ 36 | private static HashMap objectToMap(Object object) { 37 | HashMap map = new HashMap<>(); 38 | 39 | for (Field field : object.getClass().getDeclaredFields()) { 40 | field.setAccessible(true); 41 | if (field.isAnnotationPresent(Alias.class)) { 42 | Alias alia = field.getAnnotation(Alias.class); 43 | try { 44 | if (field.getType() == int.class) { 45 | System.out.printf("field: %s is int type \n", field.getName()); 46 | } else if (field.getType() == double.class) { 47 | System.out.printf("fields: %s is double type \n", field.getName()); 48 | } else if (field.getType() == String.class || field.getType() == long.class) { 49 | System.out.printf("fields: %s is String/long type \n", field.getName()); 50 | } 51 | map.put(alia.value(), field.get(object)); 52 | } catch (IllegalAccessException e) { 53 | e.printStackTrace(); 54 | } 55 | } 56 | } 57 | 58 | return map; 59 | } 60 | 61 | /** 62 | * Test methods which are be annotated with @Test 63 | */ 64 | private static void doTest(Object object) { 65 | Method[] methods = object.getClass().getDeclaredMethods(); 66 | for (Method method : methods) { 67 | if (method.isAnnotationPresent(Test.class)) { 68 | Test test = method.getAnnotation(Test.class); 69 | try { 70 | String methodName = test.value().length() == 0 ? method.getName() : test.value(); 71 | System.out.printf("Testing. methodName: %s, id: %s\n", methodName, test.id()); 72 | 73 | // static method 74 | if (Modifier.isStatic(method.getModifiers())) { 75 | method.invoke(null); 76 | } else if (Modifier.isPrivate(method.getModifiers())) { 77 | // private method 78 | method.setAccessible(true); 79 | method.invoke(object); 80 | } else { 81 | // public method 82 | method.invoke(object); 83 | } 84 | 85 | System.out.printf("PASS: Method id: %s\n", test.id()); 86 | } catch (Exception e) { 87 | System.out.printf("FAIL: Method id: %s\n", test.id()); 88 | e.printStackTrace(); 89 | } 90 | } 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /data-structure/src/annotation/runtime/Test.java: -------------------------------------------------------------------------------- 1 | package annotation.runtime; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by Jay on 4/25/17. 10 | */ 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface Test { 14 | 15 | String value() default ""; 16 | 17 | int id(); 18 | } 19 | -------------------------------------------------------------------------------- /data-structure/src/annotation/runtime/UserBean.java: -------------------------------------------------------------------------------- 1 | package annotation.runtime; 2 | 3 | public class UserBean { 4 | 5 | @Alias("user_name") 6 | public String userName; 7 | 8 | @Alias("user_id") 9 | private long userId; 10 | 11 | public UserBean(String userName, long userId) { 12 | this.userName = userName; 13 | this.userId = userId; 14 | } 15 | 16 | public String getName() { 17 | return userName; 18 | } 19 | 20 | public long getId() { 21 | return userId; 22 | } 23 | 24 | @Test(value = "static_method", id = 1) 25 | public static void staticMethod() { 26 | System.out.printf("I'm a static method\n"); 27 | } 28 | 29 | @Test(value = "public_method", id = 2) 30 | public void publicMethod() { 31 | System.out.println("I'm a public method\n"); 32 | } 33 | 34 | @Test(value = "private_method", id = 3) 35 | private void privateMethod() { 36 | System.out.println("I'm a private method\n"); 37 | } 38 | 39 | @Test(id = 4) 40 | public void testFailure() { 41 | throw new RuntimeException("Test failure"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /data-structure/src/reflection/Calculator.java: -------------------------------------------------------------------------------- 1 | package reflection; 2 | 3 | /** 4 | * Created by Jay on 4/25/17. 5 | */ 6 | public class Calculator { 7 | 8 | public int add(int a, int b) { 9 | return a + b; 10 | } 11 | 12 | public String toUpper(String a) { 13 | return a.toUpperCase(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /data-structure/src/reflection/ForArticle.java: -------------------------------------------------------------------------------- 1 | package reflection; 2 | 3 | import annotation.runtime.UserBean; 4 | 5 | import java.lang.reflect.*; 6 | 7 | /** 8 | * Created by Jay on 4/26/17. 9 | */ 10 | public class ForArticle { 11 | 12 | public static void main(String[] args) { 13 | UserBean userBean = new UserBean("Jay", 11); 14 | // printFieldsMethods(UserBean.class); 15 | try { 16 | invokeMethods(UserBean.class); 17 | } catch (Exception e) { 18 | e.printStackTrace(); 19 | } 20 | 21 | } 22 | 23 | private static void invokeMethods(Class userBeanClass) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { 24 | Method[] methods = userBeanClass.getDeclaredMethods(); 25 | for (Method method : methods) { 26 | if (method.isAnnotationPresent(Invoke.class)) { 27 | if (Modifier.isStatic(method.getModifiers())) { 28 | method.invoke(null, "wingjay"); 29 | } else { 30 | Class[] params = {String.class, long.class}; 31 | Constructor constructor = userBeanClass.getDeclaredConstructor(params); 32 | Object userBean = constructor.newInstance("wingjay", 11); 33 | if (Modifier.isPrivate(method.getModifiers())) { 34 | method.setAccessible(true); 35 | } 36 | method.invoke(userBean); 37 | } 38 | } 39 | } 40 | } 41 | 42 | private static void printFieldsMethods(Class userBeanClass) { 43 | // fields 44 | Field[] fields = userBeanClass.getDeclaredFields(); 45 | 46 | for(Field field : fields) { 47 | String fieldString = ""; 48 | fieldString += Modifier.toString(field.getModifiers()) + " "; // `private` 49 | fieldString += field.getType().getSimpleName() + " "; // `String` 50 | fieldString += field.getName(); // `userName` 51 | fieldString += ";"; 52 | System.out.println(fieldString); 53 | } 54 | 55 | _emptyLine(); 56 | 57 | // methods 58 | Method[] methods = userBeanClass.getDeclaredMethods(); 59 | for (Method method : methods) { 60 | String methodString = Modifier.toString(method.getModifiers()) + " " ; 61 | methodString += method.getReturnType().getSimpleName() + " "; 62 | methodString += method.getName() + "("; 63 | Class[] parameters = method.getParameterTypes(); 64 | for (Class parameter : parameters) { 65 | methodString += parameter.getSimpleName() + " "; 66 | } 67 | methodString += ")"; 68 | System.out.println(methodString); 69 | } 70 | 71 | _emptyLine(); 72 | 73 | // constructors 74 | Constructor[] constructors = userBeanClass.getDeclaredConstructors(); 75 | for (Constructor constructor : constructors) { 76 | String s = Modifier.toString(constructor.getModifiers()) + " "; 77 | s += constructor.getName() + "("; 78 | Class[] parameters = constructor.getParameterTypes(); 79 | for (Class parameter : parameters) { 80 | s += parameter.getSimpleName() + ", "; 81 | } 82 | s += ")"; 83 | System.out.println(s); 84 | } 85 | } 86 | 87 | private static void _emptyLine() { 88 | System.out.println("\n\n"); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /data-structure/src/reflection/HelloReflection.java: -------------------------------------------------------------------------------- 1 | package reflection; 2 | 3 | import annotation.runtime.UserBean; 4 | 5 | import java.lang.reflect.*; 6 | 7 | /** 8 | * Created by Jay on 4/25/17. 9 | */ 10 | public class HelloReflection { 11 | 12 | 13 | public static void main(String[] args) { 14 | // printClass(UserBean.class); 15 | 16 | 17 | try { 18 | Class clazz = Class.forName("annotation.runtime.UserBean"); 19 | printClass(clazz); 20 | } catch (ClassNotFoundException e) { 21 | e.printStackTrace(); 22 | } 23 | // invokeMethod(); 24 | } 25 | 26 | 27 | private static void printClass(String classPath) { 28 | try { 29 | printClass(Class.forName(classPath)); 30 | } catch (ClassNotFoundException e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | private static void printClass(Class clazz) { 36 | Field[] fields = clazz.getFields(); 37 | Field[] declaredFields = clazz.getDeclaredFields(); 38 | 39 | System.out.println("Fields: "); 40 | for (Field field : fields) { 41 | _printField(field); 42 | } 43 | _emptyLine(); 44 | 45 | System.out.println("DeclaredFields: "); 46 | for (Field field : declaredFields) { 47 | _printField(field); 48 | } 49 | _emptyLine(); 50 | 51 | Method[] methods = clazz.getMethods(); 52 | Method[] declaredMethods = clazz.getDeclaredMethods(); 53 | 54 | System.out.println("methods: "); 55 | for (Method method : methods) { 56 | _printMethod(method); 57 | } 58 | _emptyLine(); 59 | 60 | System.out.println("declaredMethods: "); 61 | for (Method method : declaredMethods) { 62 | _printMethod(method); 63 | } 64 | _emptyLine(); 65 | 66 | Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); 67 | 68 | System.out.println("DeclaredConstructors: "); 69 | for (Constructor constructor : declaredConstructors) { 70 | _printConstructor(constructor); 71 | } 72 | _emptyLine(); 73 | 74 | String packageName = clazz.getPackage().getName(); 75 | String className = clazz.getName(); 76 | String superName = clazz.getSuperclass().getName(); 77 | System.out.printf("PackageName: %s, className: %s, superName: %s", packageName, className, superName); 78 | } 79 | 80 | private static void invokeMethod() { 81 | Class clazz = Calculator.class; 82 | 83 | Integer addResult; 84 | try { 85 | Method method = clazz.getMethod("add", new Class[]{int.class, int.class}); 86 | addResult = (Integer) method.invoke(new Calculator(), 1, 2); 87 | System.out.printf("add result: %s", String.valueOf(addResult)); 88 | } catch (Exception e) { 89 | e.printStackTrace(); 90 | } 91 | } 92 | 93 | private static void printObject(Object object) { 94 | 95 | } 96 | 97 | private static void _printField(Field field) { 98 | System.out.println(Modifier.toString(field.getModifiers()) + " " + field.getType().getSimpleName() + " " + field.getName()); 99 | } 100 | 101 | private static void _printMethod(Method method) { 102 | String methodString = Modifier.toString(method.getModifiers()) + " " + method.getReturnType().getSimpleName() + " " + method.getName() + "("; 103 | Class[] clazzList = method.getParameterTypes(); 104 | for (Class clazz : clazzList) { 105 | methodString += clazz.getSimpleName() + " "; 106 | } 107 | methodString += ")"; 108 | System.out.println(methodString); 109 | } 110 | 111 | private static void _printConstructor(Constructor constructor) { 112 | String constructorString = constructor.getName() + "("; 113 | Class[] types = constructor.getParameterTypes(); 114 | for (Class type : types) { 115 | constructorString += type.getSimpleName() + " "; 116 | } 117 | constructorString += ")"; 118 | System.out.println(constructorString); 119 | } 120 | 121 | private static void _emptyLine() { 122 | System.out.println("\n\n"); 123 | } 124 | 125 | } 126 | 127 | 128 | -------------------------------------------------------------------------------- /data-structure/src/reflection/Invoke.java: -------------------------------------------------------------------------------- 1 | package reflection; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created by Jay on 4/26/17. 10 | */ 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface Invoke { 14 | } 15 | -------------------------------------------------------------------------------- /design-pattern/src/HelloBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Jay on 3/24/17. 3 | */ 4 | public class HelloBuilder { 5 | 6 | public static void main(String[] args) { 7 | Person person = new Person.Builder("Jay", 1).age(20).school("sjtu").sex(1).build(); 8 | Person person2 = new Person.Builder("lulu", 10).age(18).sex(0).build(); 9 | 10 | System.out.println("person: " + person.toString() + "\n"); 11 | System.out.println("person2: " + person2.toString() + "\n"); 12 | } 13 | 14 | static class Person { 15 | private long id; // must larget than 0 16 | private String name; // must not be null 17 | private int age; 18 | private int sex; 19 | private String school; 20 | 21 | private Person(Builder builder) { 22 | if (builder.name == null || builder.name.length() == 0) { 23 | throw new IllegalArgumentException("name should be null or empty"); 24 | } 25 | if (builder.id <= 0) { 26 | throw new IllegalArgumentException("id must be larger zero"); 27 | } 28 | this.name = builder.name; 29 | this.age = builder.age; 30 | this.sex = builder.sex; 31 | this.school = builder.school; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(100); 37 | sb.append("name: "); 38 | sb.append(name); 39 | sb.append("; age: "); 40 | sb.append(age); 41 | sb.append("; id: "); 42 | sb.append(id); 43 | sb.append("; sex: "); 44 | sb.append(sex); 45 | return sb.toString(); 46 | } 47 | 48 | static class Builder { 49 | private String name; 50 | private int age = 18; 51 | private long id; 52 | private int sex = 1; 53 | private String school; 54 | 55 | public Builder(String name, int id) { 56 | this.name = name; 57 | this.id = id; 58 | } 59 | 60 | public Builder age(int age) { 61 | this.age = age; 62 | return this; 63 | } 64 | 65 | public Builder sex(int sex) { 66 | this.sex = sex; 67 | return this; 68 | } 69 | 70 | public Builder school(String school) { 71 | this.school = school; 72 | return this; 73 | } 74 | 75 | public Person build() { 76 | return new Person(this); 77 | } 78 | } 79 | } 80 | 81 | 82 | } -------------------------------------------------------------------------------- /design-pattern/src/proxy/ISecondSubject.java: -------------------------------------------------------------------------------- 1 | package proxy; 2 | 3 | /** 4 | * Created by wingjay on 10/02/2018. 5 | */ 6 | public interface ISecondSubject { 7 | void doC(); 8 | } 9 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/ISubject.java: -------------------------------------------------------------------------------- 1 | package proxy; 2 | 3 | /** 4 | * Created by wingjay on 06/11/2017. 5 | */ 6 | interface ISubject { 7 | void doA(); 8 | void doB(String url); 9 | } 10 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/MethodTimingProxy.java: -------------------------------------------------------------------------------- 1 | package proxy; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Proxy; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by wingjay on 06/11/2017. 12 | */ 13 | public class MethodTimingProxy implements InvocationHandler { 14 | 15 | private Object target; 16 | 17 | public Object bind(Object realObject) { 18 | this.target = realObject; 19 | System.out.println("abc".substring(0, 1)); 20 | int[] r = {0,0,0,0}; 21 | fourSum(r, 0); 22 | return Proxy.newProxyInstance(realObject.getClass().getClassLoader(), 23 | realObject.getClass().getInterfaces(), 24 | this); 25 | } 26 | public List> fourSum(int[] nums, int target) { 27 | if(nums == null || nums.length < 4) { 28 | return new ArrayList<>(); 29 | } 30 | 31 | Arrays.sort(nums); 32 | List> ret = new ArrayList<>(); 33 | int length = nums.length; 34 | for(int i=0; i0 && nums[i] == nums[i-1]) { continue; } 36 | threeSum(nums, i+1, -nums[i], ret); 37 | } 38 | 39 | return ret; 40 | } 41 | 42 | private void threeSum(int[] nums, int start, int target, List> ret) { 43 | int length = nums.length; 44 | for(int i=start; i l = new ArrayList<>(4); 51 | l.add(-target); 52 | l.add(nums[i]); 53 | l.add(nums[left]); 54 | l.add(nums[right]); 55 | ret.add(l); 56 | 57 | left++; 58 | right--; 59 | while(left < right && nums[left] == nums[left-1]) { 60 | left++; 61 | } 62 | while(left < right && nums[right] == nums[right+1]) { 63 | right--; 64 | } 65 | } else if(sum < target) { 66 | left++; 67 | } else { 68 | right--; 69 | } 70 | } 71 | } 72 | } 73 | @Override 74 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 75 | long start = System.nanoTime(); 76 | Object result = method.invoke(target, args); 77 | System.out.println(String.format("methods %s, consume time: %s", method.getName(), System.nanoTime() - start)); 78 | return result; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/ProxyTest.java: -------------------------------------------------------------------------------- 1 | package proxy; 2 | 3 | import proxy.httpRecorder.HttpLoggerProxy; 4 | import proxy.httpRecorder.IHandler; 5 | import proxy.httpRecorder.RequestHandler; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * Created by wingjay on 06/11/2017. 12 | */ 13 | public class ProxyTest { 14 | 15 | public static void main(String[] args) { 16 | System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); 17 | testISubject(); 18 | // testMap(); 19 | // testHttpLogging(new RequestHandler.Request("https://google.com", "key=value")); 20 | // testHttpLogging(new RequestHandler.Request("https://baidu.com", "key2=value2")); 21 | } 22 | 23 | private static void testISubject() { 24 | ISubject iSubject = (ISubject) new MethodTimingProxy().bind(new RealSubject()); 25 | iSubject.doA(); 26 | } 27 | 28 | private static void testMap() { 29 | Map map = (Map) new MethodTimingProxy().bind(new HashMap<>()); 30 | map.put("First", "1"); 31 | map.put("Second", "2"); 32 | System.out.println(map.get("First")); 33 | System.out.println(map.get("Second")); 34 | } 35 | 36 | private static void testHttpLogging(RequestHandler.Request request) { 37 | IHandler handler = (IHandler) new HttpLoggerProxy().bind(new RequestHandler()); 38 | handler.handle(request); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/RealSubject.java: -------------------------------------------------------------------------------- 1 | package proxy; 2 | 3 | /** 4 | * Created by wingjay on 06/11/2017. 5 | */ 6 | public class RealSubject implements ISubject, ISecondSubject { 7 | @Override 8 | public void doA() { 9 | System.out.println("RealSubject doA"); 10 | } 11 | 12 | @Override 13 | public void doB(String url) { 14 | System.out.println("RealSubject doB"); 15 | } 16 | 17 | @Override 18 | public void doC() { 19 | System.out.println("RealSubject doC"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/httpRecorder/HttpLoggerProxy.java: -------------------------------------------------------------------------------- 1 | package proxy.httpRecorder; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Proxy; 6 | 7 | /** 8 | * Created by wingjay on 31/01/2018. 9 | */ 10 | public class HttpLoggerProxy implements InvocationHandler { 11 | private Object target; 12 | 13 | public Object bind(Object o) { 14 | this.target = o; 15 | return Proxy.newProxyInstance(o.getClass().getClassLoader(), 16 | o.getClass().getInterfaces(), 17 | this); 18 | } 19 | @Override 20 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 21 | if (method.getName().equals("handle") 22 | && args[0].getClass() == RequestHandler.Request.class) { 23 | RequestHandler.Request r = (RequestHandler.Request) args[0]; 24 | System.out.println("Request. Url: " + r.url + "; params: " + r.params); 25 | RequestHandler.Response response = (RequestHandler.Response) method.invoke(target, args); 26 | System.out.println("Response. StatusCode: " + response.statusCode + "; response: " + response.response); 27 | return response; 28 | } 29 | return method.invoke(target, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/httpRecorder/IHandler.java: -------------------------------------------------------------------------------- 1 | package proxy.httpRecorder; 2 | 3 | /** 4 | * Created by wingjay on 31/01/2018. 5 | */ 6 | public interface IHandler { 7 | RequestHandler.Response handle(RequestHandler.Request request); 8 | } 9 | -------------------------------------------------------------------------------- /design-pattern/src/proxy/httpRecorder/RequestHandler.java: -------------------------------------------------------------------------------- 1 | package proxy.httpRecorder; 2 | 3 | /** 4 | * Created by wingjay on 31/01/2018. 5 | */ 6 | public class RequestHandler implements IHandler { 7 | 8 | @Override 9 | public Response handle(Request request) { 10 | System.out.println("Parse doA..."); 11 | System.out.println("Read database..."); 12 | System.out.println("Assemble result..."); 13 | return new Response(200, "PersonJson"); 14 | } 15 | 16 | public static class Request { 17 | public Request(String url, String params) { 18 | this.url = url; 19 | this.params = params; 20 | } 21 | String url; 22 | String params; 23 | } 24 | public static class Response { 25 | Response(int statusCode, String response) { 26 | this.statusCode = statusCode; 27 | this.response = response; 28 | } 29 | int statusCode; 30 | String response; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-pattern/src/singleton/BadSingleInstance.java: -------------------------------------------------------------------------------- 1 | package singleton; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Created by Jay on 3/24/17. 7 | */ 8 | public class BadSingleInstance implements HelloSingleInstance.ITestSingleInstance { 9 | private final static Random random = new Random(); 10 | private int id = random.nextInt(1000); 11 | 12 | private static BadSingleInstance INSTANCE; 13 | 14 | private BadSingleInstance() {} 15 | 16 | public static BadSingleInstance getInstance() { 17 | if (INSTANCE == null) { 18 | try { 19 | Thread.sleep(100); 20 | } catch (Exception e) { 21 | e.printStackTrace(); 22 | } 23 | INSTANCE = new BadSingleInstance(); 24 | } 25 | return INSTANCE; 26 | } 27 | 28 | @Override 29 | public int getId() { 30 | return id; 31 | } 32 | } -------------------------------------------------------------------------------- /design-pattern/src/singleton/HelloSingleInstance.java: -------------------------------------------------------------------------------- 1 | package singleton; 2 | 3 | import java.util.ArrayList; 4 | import java.util.concurrent.CountDownLatch; 5 | 6 | /** 7 | * Three methods for single instance implementation. 8 | */ 9 | public class HelloSingleInstance { 10 | 11 | public static void main(String[] args) { 12 | // testSingleInstance(Type.BadSingleInstance); 13 | // testSingleInstance(Type.SingleEnum); 14 | // testSingleInstance(Type.SingleElvis); 15 | testSingleInstance(Type.SingleJay); 16 | } 17 | 18 | private static void testSingleInstance(Type type) { 19 | int count = 10; 20 | ArrayList arrayList = new ArrayList<>(count); 21 | CountDownLatch latch = new CountDownLatch(count); 22 | for (int i=0; i map = new HashMap<>(2); 62 | // map.put(new PhoneNumberWithoutHashcode(86, 123123), "Jay"); 63 | // System.out.println("testEqualsNonHashcode Name must be Jay: " + map.get(new PhoneNumberWithoutHashcode(86, 123))); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /effective-java/src/equals_hashcode/PhoneNumber.java: -------------------------------------------------------------------------------- 1 | package equals_hashcode; 2 | /** 3 | * Created by Jay on 3/24/17. 4 | */ 5 | public class PhoneNumber implements Comparable { 6 | protected final short countryCode; 7 | protected final short number; 8 | 9 | public PhoneNumber(int countryCode, int number) { 10 | this.countryCode = (short) countryCode; 11 | this.number = (short) number; 12 | } 13 | 14 | @Override 15 | public boolean equals(Object obj) { 16 | // 1. check == reference 17 | if (this == obj) 18 | return true; 19 | 20 | // 2. check obj instance 21 | if (!(obj instanceof PhoneNumber)) 22 | return false; 23 | 24 | // 3. check logic value 25 | PhoneNumber target = (PhoneNumber) obj; 26 | return target.number == this.number 27 | && target.countryCode == this.countryCode; 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return (31 * this.countryCode) + this.number; 33 | } 34 | 35 | @Override 36 | public int compareTo(Object o) { 37 | if (this == o) { 38 | return 0; 39 | } 40 | 41 | if (!(o instanceof PhoneNumber)) { 42 | throw new IllegalArgumentException("o must be instance of PhoneNumber"); 43 | } 44 | 45 | PhoneNumber target = (PhoneNumber) o; 46 | if (countryCode < target.countryCode) 47 | return -1; 48 | if (countryCode > target.countryCode) 49 | return 1; 50 | 51 | if (number < target.number) 52 | return -1; 53 | if (number > target.number) 54 | return 1; 55 | 56 | return 0; 57 | } 58 | } -------------------------------------------------------------------------------- /effective-java/src/equals_hashcode/PhoneNumberWithoutHashcode.java: -------------------------------------------------------------------------------- 1 | package equals_hashcode; 2 | 3 | /** 4 | * Created by Jay on 3/24/17. 5 | */ 6 | public class PhoneNumberWithoutHashcode { 7 | 8 | protected final short countryCode; 9 | protected final short number; 10 | 11 | public PhoneNumberWithoutHashcode(int countryCode, int number) { 12 | this.countryCode = (short) countryCode; 13 | this.number = (short) number; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object obj) { 18 | // 1. check == reference 19 | if (this == obj) 20 | return true; 21 | 22 | // 2. check obj instance 23 | if (!(obj instanceof PhoneNumberWithoutHashcode)) 24 | return false; 25 | 26 | // 3. check logic value 27 | PhoneNumberWithoutHashcode target = (PhoneNumberWithoutHashcode) obj; 28 | return target.number == this.number 29 | && target.countryCode == this.countryCode; 30 | } 31 | } -------------------------------------------------------------------------------- /multi-thread/src/ForArticle.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is explanation for article: 3 | */ 4 | public class ForArticle { 5 | 6 | public static void main(String[] args) { 7 | // demo1(); 8 | // demo2(); 9 | demo3(); 10 | 11 | } 12 | 13 | /** 14 | * random output 15 | */ 16 | private static void demo1() { 17 | Thread A = new Thread(new Runnable() { 18 | @Override 19 | public void run() { 20 | printNumber("A"); 21 | } 22 | }); 23 | 24 | Thread B = new Thread(new Runnable() { 25 | @Override 26 | public void run() { 27 | printNumber("B"); 28 | } 29 | }); 30 | 31 | A.start(); 32 | B.start(); 33 | } 34 | 35 | /** 36 | * A 1, A 2, A 3, B 1, B 2, B 3 37 | */ 38 | private static void demo2() { 39 | Thread A = new Thread(new Runnable() { 40 | @Override 41 | public void run() { 42 | printNumber("A"); 43 | } 44 | }); 45 | 46 | Thread B = new Thread(new Runnable() { 47 | @Override 48 | public void run() { 49 | System.out.println("B 开始等待 A"); 50 | try { 51 | A.join(); 52 | } catch (InterruptedException e) { 53 | e.printStackTrace(); 54 | } 55 | 56 | printNumber("B"); 57 | } 58 | }); 59 | 60 | A.start(); 61 | B.start(); 62 | } 63 | 64 | /** 65 | * A 1, B 1, B 2, B 3, A 2, A 3 66 | */ 67 | private static void demo3() { 68 | Object lock = new Object(); 69 | 70 | Thread A = new Thread(new Runnable() { 71 | @Override 72 | public void run() { 73 | System.out.println("INFO: A 等待锁"); 74 | synchronized (lock) { 75 | System.out.println("INFO: A 得到了锁 lock"); 76 | System.out.println("A 1"); 77 | try { 78 | System.out.println("INFO: A 准备进入等待状态,调用 lock.wait() 放弃锁 lock 的控制权"); 79 | lock.wait(); 80 | } catch (InterruptedException e) { 81 | e.printStackTrace(); 82 | } 83 | System.out.println("INFO: 有人唤醒了 A, A 重新获得锁 lock"); 84 | System.out.println("A 2"); 85 | System.out.println("A 3"); 86 | } 87 | 88 | } 89 | }); 90 | 91 | Thread B = new Thread(new Runnable() { 92 | @Override 93 | public void run() { 94 | System.out.println("INFO: B 等待锁"); 95 | synchronized (lock) { 96 | System.out.println("INFO: B 得到了锁 lock"); 97 | System.out.println("B 1"); 98 | System.out.println("B 2"); 99 | System.out.println("B 3"); 100 | 101 | System.out.println("INFO: B 打印完毕,调用 lock.notify() 方法"); 102 | lock.notify(); 103 | } 104 | } 105 | }); 106 | 107 | A.start(); 108 | B.start(); 109 | } 110 | 111 | private static void printNumber(String threadName) { 112 | int j=0; 113 | while (j++ < 3) { 114 | try { 115 | Thread.sleep(100); 116 | } catch (InterruptedException e) { 117 | e.printStackTrace(); 118 | } 119 | System.out.println(threadName + " print: " + j); 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /multi-thread/src/HelloConcurrent.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | import java.util.concurrent.*; 3 | 4 | /** 5 | * Concurrent library learning 6 | */ 7 | public class HelloConcurrent { 8 | 9 | public static void main(String[] args) { 10 | // runDAfterABC(); 11 | 12 | runABCWhenAllReady(); 13 | 14 | // doTaskWithResultInWorker(); 15 | } 16 | 17 | private static void doTaskWithResultInWorker() { 18 | //创建线程池 19 | ExecutorService executor = Executors.newCachedThreadPool(); 20 | 21 | Callable callable = new Callable() { 22 | @Override 23 | public Integer call() throws Exception { 24 | System.out.println("Task starts"); 25 | Thread.sleep(1000); 26 | int result = 0; 27 | for (int i=0; i<=100; i++) { 28 | result += i; 29 | } 30 | System.out.println("Task finished and return result"); 31 | return result; 32 | } 33 | }; 34 | 35 | FutureTask futureTask = new FutureTask(callable) { 36 | @Override 37 | protected void done() { 38 | System.out.println("Before futureTask.get(). ThreadName: " + Thread.currentThread().getName()); 39 | try { 40 | System.out.println("Result: " + get()); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } catch (ExecutionException e) { 44 | e.printStackTrace(); 45 | } 46 | System.out.println("After futureTask.get()"); 47 | } 48 | }; 49 | executor.submit(futureTask); 50 | executor.shutdown(); 51 | System.out.println("End of main thread. ThreadName: " + Thread.currentThread().getName()); 52 | } 53 | 54 | 55 | /** 56 | * A B C starts running when all three are ready. 57 | */ 58 | private static void runABCWhenAllReady() { 59 | int runner = 3; 60 | CyclicBarrier cyclicBarrier = new CyclicBarrier(runner); 61 | 62 | final Random random = new Random(); 63 | for (char runnerName='A'; runnerName <= 'C'; runnerName++) { 64 | final String rN = String.valueOf(runnerName); 65 | new Thread(new Runnable() { 66 | @Override 67 | public void run() { 68 | long prepareTime = random.nextInt(10000) + 100; 69 | System.out.println(rN + " is preparing for time: " + prepareTime); 70 | try { 71 | Thread.sleep(prepareTime); 72 | } catch (Exception e) { 73 | e.printStackTrace(); 74 | } 75 | 76 | try { 77 | System.out.println(rN + " is prepared, waiting for others"); 78 | cyclicBarrier.await(); 79 | } catch (InterruptedException e) { 80 | e.printStackTrace(); 81 | } catch (BrokenBarrierException e) { 82 | e.printStackTrace(); 83 | } 84 | 85 | System.out.println(rN + " starts running"); 86 | } 87 | }).start(); 88 | } 89 | } 90 | 91 | /** 92 | * Only if A, B, C are all finished, D starts working 93 | */ 94 | private static void runDAfterABC() { 95 | int worker = 3; 96 | CountDownLatch countDownLatch = new CountDownLatch(worker); 97 | 98 | new Thread(new Runnable() { 99 | @Override 100 | public void run() { 101 | System.out.println("D is waiting for other three threads"); 102 | try { 103 | countDownLatch.await(); 104 | System.out.println("All done, D starts working"); 105 | } catch (InterruptedException e) { 106 | e.printStackTrace(); 107 | } 108 | 109 | } 110 | }).start(); 111 | 112 | for (char threadName='A'; threadName <= 'C'; threadName++) { 113 | final String tN = String.valueOf(threadName); 114 | new Thread(new Runnable() { 115 | @Override 116 | public void run() { 117 | System.out.println(tN + " is working"); 118 | try { 119 | Thread.sleep(100); 120 | } catch (Exception e) { 121 | e.printStackTrace(); 122 | } 123 | 124 | System.out.println(tN + " finished"); 125 | countDownLatch.countDown(); 126 | } 127 | }).start(); 128 | } 129 | } 130 | 131 | } -------------------------------------------------------------------------------- /multi-thread/src/HelloProducerConsumer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Producer Consumer model 3 | */ 4 | public class HelloProducerConsumer { 5 | 6 | public static void main(String[] args) { 7 | final ProductCache cache = new ProductCache<>(); 8 | 9 | new Thread(new Runnable() { 10 | @Override 11 | public void run() { 12 | Producer producer = new Producer(cache); 13 | producer.start(); 14 | } 15 | }).start(); 16 | 17 | 18 | new Thread(new Runnable() { 19 | @Override 20 | public void run() { 21 | Consumer consumer = new Consumer(cache); 22 | consumer.start(); 23 | } 24 | }).start(); 25 | } 26 | 27 | static class ProductCache { 28 | // used to stored one product instance 29 | 30 | T product; 31 | boolean isPoped = true; 32 | 33 | final Object lock = new Object(); 34 | 35 | public T pop() { 36 | synchronized (lock) { 37 | if (isPoped) { 38 | try { 39 | lock.wait(); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | System.out.println(" pop " + product); 45 | isPoped = true; 46 | lock.notify(); 47 | return product; 48 | } 49 | 50 | } 51 | 52 | public void put(T t) { 53 | synchronized (lock) { 54 | if (!isPoped) { 55 | try { 56 | lock.wait(); 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | System.out.println("put " + t); 62 | this.product = t; 63 | isPoped = false; 64 | lock.notify(); 65 | } 66 | } 67 | } 68 | 69 | static class Producer { 70 | 71 | private ProductCache productCache; 72 | 73 | public Producer(ProductCache productCache) { 74 | this.productCache = productCache; 75 | } 76 | 77 | public void start() { 78 | Integer i = 0; 79 | while (i < 10) { 80 | productCache.put(i++); 81 | } 82 | } 83 | } 84 | 85 | static class Consumer { 86 | private ProductCache productCache; 87 | 88 | public Consumer(ProductCache productCache) { 89 | this.productCache = productCache; 90 | } 91 | 92 | public void start() { 93 | while (true) { 94 | productCache.pop(); 95 | } 96 | } 97 | } 98 | 99 | } -------------------------------------------------------------------------------- /multi-thread/src/HelloThreadLocal.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | 3 | public class HelloThreadLocal { 4 | 5 | public static void main(String args[]) throws IOException { 6 | // testThreadLocalVariable(); 7 | 8 | testOutsideVariable(); 9 | } 10 | 11 | static int innitialValue = 0; 12 | static ThreadLocal threadLocalValue = new ThreadLocal(){ 13 | @Override 14 | protected Integer initialValue() { 15 | return 10; 16 | } 17 | }; 18 | private static void testOutsideVariable() { 19 | for (int i=0; i<100; i++) { 20 | new Thread(new Runnable() { 21 | @Override 22 | public void run() { 23 | innitialValue += 10; 24 | threadLocalValue.set(threadLocalValue.get() + 10); 25 | System.out.println("innitialValue: " + innitialValue + 26 | ", threadLocalValue: " + threadLocalValue.get() + 27 | ", in " + Thread.currentThread().getName()); 28 | } 29 | }).start(); 30 | } 31 | } 32 | 33 | private static void testThreadLocalVariable() { 34 | CommonRunnable runnable = new CommonRunnable(); 35 | for (int i=0; i<100; i++) { 36 | new Thread(runnable).start(); 37 | } 38 | } 39 | 40 | static class CommonRunnable implements Runnable { 41 | int localInt = 0; 42 | ThreadLocal threadLocalInt = new ThreadLocal() { 43 | @Override 44 | protected Integer initialValue() { 45 | return 0; 46 | } 47 | }; 48 | 49 | @Override 50 | public void run() { 51 | localInt += 10; 52 | threadLocalInt.set(threadLocalInt.get() + 10); 53 | System.out.println("localInt: " + localInt + 54 | ", threadLocalCount: " + threadLocalInt.get()+ 55 | ", in " + Thread.currentThread().getName()); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /multi-thread/src/HelloVolatile.java: -------------------------------------------------------------------------------- 1 | import java.util.Objects; 2 | import java.util.concurrent.CountDownLatch; 3 | 4 | /** 5 | * Created by Jay on 3/22/17. 6 | */ 7 | public class HelloVolatile { 8 | public static void main(String[] args) { 9 | // testVolatile(); 10 | // printIncNumberByThreeThreads(); 11 | // testWaitNotify(); 12 | testSingleton(); 13 | // testSynchronizedObject(); 14 | } 15 | 16 | private static void testSingleton() { 17 | for (int i=0; i<100; i++) { 18 | final int index = i; 19 | new Thread(new Runnable() { 20 | @Override 21 | public void run() { 22 | System.out.println("Want to fetch singleton object in thread: " + index); 23 | getSingleton(); 24 | } 25 | }).start(); 26 | } 27 | } 28 | 29 | static Object singleton; 30 | private synchronized static Object getSingleton() { 31 | if (singleton == null) { 32 | try { 33 | Thread.sleep(100); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | System.out.println("create singleTon, this method must only occur once"); 38 | singleton = new Object(); 39 | } 40 | return singleton; 41 | } 42 | 43 | private static void testSynchronizedObject() { 44 | final Object lock = new Object(); 45 | 46 | Thread thread1 = new Thread(new Runnable() { 47 | @Override 48 | public void run() { 49 | synchronized (lock) { 50 | System.out.println("thread1 running, start sleep"); 51 | try { 52 | Thread.sleep(1000); 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | } 56 | System.out.println("thread1 finish sleep"); 57 | } 58 | } 59 | }); 60 | 61 | Thread thread2 = new Thread(new Runnable() { 62 | @Override 63 | public void run() { 64 | System.out.println("thread2 running"); 65 | } 66 | }); 67 | 68 | Thread thread3 = new Thread(new Runnable() { 69 | @Override 70 | public void run() { 71 | synchronized (lock) { 72 | System.out.println("thread3 running, it will wait for thread1 ending"); 73 | } 74 | } 75 | }); 76 | 77 | thread1.start(); 78 | thread2.start(); 79 | thread3.start(); 80 | } 81 | 82 | private static void testWaitNotify() { 83 | final Object lock = new Object(); 84 | 85 | Thread thread1 = new Thread(new Runnable() { 86 | @Override 87 | public void run() { 88 | synchronized (lock) { 89 | System.out.println("thread1 running, start waiting lock"); 90 | try { 91 | lock.wait(); 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | System.out.println("thread1 finish wait"); 96 | } 97 | } 98 | }); 99 | 100 | Thread thread2 = new Thread(new Runnable() { 101 | @Override 102 | public void run() { 103 | synchronized (lock) { 104 | System.out.println("thread2 running, ready notify lock"); 105 | lock.notify(); 106 | System.out.println("thread2 running, notified lock"); 107 | } 108 | } 109 | }); 110 | 111 | thread1.start(); 112 | thread2.start(); 113 | } 114 | 115 | static int count = 1; 116 | public static void printIncNumberByThreeThreads() { 117 | HelloVolatile helloVolatile = new HelloVolatile(); 118 | for (int i=1; i<=3; i++) { 119 | new PrintThread(i, helloVolatile).start(); 120 | } 121 | } 122 | 123 | private static class PrintThread extends Thread { 124 | // use wait/notify for better performance 125 | int id; 126 | final HelloVolatile helloVolatile; 127 | 128 | PrintThread(int id, HelloVolatile helloVolatile) { 129 | this.id = id; 130 | this.helloVolatile = helloVolatile; 131 | } 132 | 133 | @Override 134 | public void run() { 135 | super.run(); 136 | synchronized (helloVolatile) { 137 | while (count <= 750) { 138 | System.out.println("Thread is working, " + id); 139 | if (((count-1) / 5) % 3 == (id-1)) { 140 | System.out.println("Thread " + id + " : " + count++); 141 | helloVolatile.notifyAll(); 142 | } else { 143 | try { 144 | helloVolatile.wait(); 145 | } catch (Exception e) { 146 | e.printStackTrace(); 147 | } 148 | } 149 | } 150 | } 151 | 152 | } 153 | } 154 | 155 | private static class SimplePrintThread extends Thread { 156 | // don't use wait/notify, it will do more useless work in the while(){...} 157 | int id; 158 | HelloVolatile helloVolatile; 159 | 160 | SimplePrintThread(int id, HelloVolatile helloVolatile) { 161 | this.id = id; 162 | this.helloVolatile = helloVolatile; 163 | } 164 | 165 | @Override 166 | public void run() { 167 | super.run(); 168 | while (count <= 75) { 169 | System.out.println("Thread is working, " + id); 170 | if (((count-1) / 5) % 3 == (id-1)) { 171 | System.out.println("Thread " + id + " : " + count++); 172 | } 173 | } 174 | } 175 | } 176 | 177 | public static void testVolatile() { 178 | for (int i=0; i<2000; i++) { 179 | new Thread(String.valueOf(i)) { 180 | @Override 181 | public void run() { 182 | super.run(); 183 | try { 184 | Thread.sleep(10); 185 | } catch (Exception e) { 186 | 187 | } 188 | System.out.println("prepare to add : " + count + " in thread: " + Thread.currentThread().getName()); 189 | count++; 190 | } 191 | }.start(); 192 | } 193 | 194 | try { 195 | Thread.sleep(100); 196 | } catch (Exception e) {} 197 | System.out.println("count: " + count); 198 | } 199 | 200 | } -------------------------------------------------------------------------------- /multi-thread/src/Test.java: -------------------------------------------------------------------------------- 1 | import java.util.Collections; 2 | import java.util.HashMap; 3 | import java.util.HashSet; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Jay on 4/10/17. 8 | */ 9 | public class Test { 10 | 11 | public static void main(String[] args) { 12 | test2(); 13 | 14 | } 15 | 16 | private static void test_1() { 17 | int[] array = {-10, 1, 3, 5, 7, 9, 10, 12, 14, 16, 19, 20, 25, 27, 29, 30, 40, 45, 49, 50, 60}; 18 | int sum = 50; 19 | HashMap result = (HashMap) findSum(array, sum); 20 | System.out.println(result); 21 | } 22 | 23 | private static Map findSum(int[] array, int sum) { 24 | int length = array.length; 25 | if (sum < array[0] || (sum >= 2 * array[length - 1])) { 26 | return new HashMap<>(0); 27 | } 28 | 29 | HashMap result = new HashMap<>(length/2 + 1); 30 | HashSet set = new HashSet<>(length); 31 | 32 | for (int i=0; i= sum) { 38 | break; 39 | } 40 | if ((array[i] != sum - array[i]) && set.contains(sum - array[i])) { 41 | result.put(array[i], sum - array[i]); 42 | } 43 | } 44 | 45 | return result; 46 | } 47 | 48 | private static void test2() { 49 | int[] array = {3, 4, 3, 2, 1}; 50 | int[] result = sort(array); 51 | for (int i=0; i