├── .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);
41 | map.put(p1, "Jay");
42 | System.out.println("testEqualsHashcode Name must be Jay: " + map.get(p2));
43 | // different object in HashMap, but same result.
44 | }
45 |
46 | private static void testEqualsNonHashcode() {
47 | PhoneNumberWithoutHashcode p1 = new PhoneNumberWithoutHashcode(86, 123123);
48 | PhoneNumberWithoutHashcode p2 = new PhoneNumberWithoutHashcode(86, 123123);
49 | System.out.println("p1.equals(p2)=" + p1.equals(p2));
50 | System.out.println("p1.hashcode()=" + p1.hashCode());
51 | System.out.println("p2.hashcode()=" + p2.hashCode());
52 |
53 |
54 | int p1hash=0;
55 | int p2hash=0;
56 | p1hash = (p1.hashCode()) ^ (p1hash >>> 16);
57 | p2hash = (p2.hashCode()) ^ (p2hash >>> 16);
58 | System.out.println("p1 hash() " + p1hash);
59 | System.out.println("p2 hash() " + p2hash);
60 |
61 | // HashMap 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