diff --git a/group01/954958168/.gitignore b/group01/954958168/.gitignore
new file mode 100644
index 0000000000..e8b4e006b1
--- /dev/null
+++ b/group01/954958168/.gitignore
@@ -0,0 +1,9 @@
+build
+target/
+*.class
+# ide
+.settings/
+.project
+.classpath
+.idea/
+*.iml
diff --git a/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LinkedList.java b/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LinkedList.java
index 504e73580b..b4e5fe5027 100644
--- a/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LinkedList.java
+++ b/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LinkedList.java
@@ -84,7 +84,7 @@ public Object[] toArray() {
Object[] objects = new Object[size];
Node first = head.next;
int pos = 0;
- while (first!= null) {
+ while (first != null) {
objects[pos++] = first.data;
first = first.next;
}
@@ -126,4 +126,196 @@ private Node(Object data) {
this.data = data;
}
}
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse() {
+ Node newHead = new Node(null);
+ Node node = head.next;
+ while (node != null) {
+ Node temp = node.next;
+ node.next = newHead.next;
+ newHead.next = node;
+ node = temp;
+ }
+ head = newHead;
+ }
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+ */
+ public void removeFirstHalf() {
+ int removeLen = size / 2;
+ if (size <= 1) {
+ head.next = null;
+ size = 0;
+ return;
+ }
+ for (int i = 0; i < removeLen; i++) {
+ Node point = head.next;
+ head.next = point.next;
+ point.next = null;
+ size--;
+ }
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ *
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length) {
+ if (i < 0 || i >= size || length < 1) throw new IndexOutOfBoundsException("索引超出范围");
+ int endIndex = Math.min(i + length, size);
+ Node preNode = head;
+ Node endNode = head.next;
+ for (int index = 0; index < endIndex; index++) {
+ if (index < i) {
+ preNode = endNode;
+ }
+ endNode = endNode.next;
+ }
+
+ preNode.next = endNode;
+ size = size - (endIndex - i);
+ }
+
+ /**
+ * 假定当前链表和list均包含已升序排列的整数
+ * 从当前链表中取出那些list所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ *
+ * @param list
+ */
+ public int[] getElements(LinkedList list) {
+ if (list == null) return new int[0];
+ Iterator iterator = list.iterator();
+ int[] result = new int[list.size()];
+ int index = 0;
+ while (iterator.hasNext()) {
+ Integer next = (Integer) iterator.next();
+ result[index] = (Integer) this.get(next);
+ index++;
+ }
+ return result;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在list中出现的元素
+ *
+ * @param list
+ */
+
+ public void subtract(LinkedList list) {
+ if (list == null) return;
+ Iterator iterator = this.iterator();
+ while (iterator.hasNext()) {
+ Object element = iterator.next();
+ if (contain(element, list)) {
+ iterator.remove();
+ }
+ }
+ }
+
+ private boolean contain(Object element, LinkedList list) {
+ Iterator iterator = list.iterator();
+ while (iterator.hasNext()) {
+ Object next = iterator.next();
+ if (next == element) return true;
+ }
+ return false;
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues() {
+ Node pre = head;
+ Node cur = head.next;
+ while (cur != null) {
+ if (pre.data == cur.data) {
+ Node node = cur.next;
+ while (node != null && node.data == pre.data) {
+ node = node.next;
+ size--;
+ }
+ pre.next = node;
+ cur = node;
+ size--;
+ } else {
+ pre = cur;
+ cur = cur.next;
+ }
+ }
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ *
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max) {
+ if (min >= max) return;
+ Node cur = head;
+ Node start = null;
+ Node end = null;
+ Integer startIndex = null;
+ Integer endIndex = size - 1;
+ Integer index = -1;
+ while (cur.next != null) {
+ if (start == null && (Integer) cur.next.data > min) {
+ start = cur;
+ startIndex = index;
+ }
+ if ((Integer) cur.next.data >= max) {
+ end = cur.next;
+ endIndex = index;
+ break;
+ }
+ cur = cur.next;
+ index++;
+ }
+ if (start != null) {
+ start.next = end;
+ size = size - (endIndex - startIndex);
+ }
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ *
+ * @param list
+ */
+ public LinkedList intersection(LinkedList list) {
+ if (list == null) return this;
+ LinkedList intersection = new LinkedList();
+ Node node1 = this.head.next;
+ Node node2 = list.head.next;
+ while (node1 != null && node2 != null) {
+ if((Integer)node1.data < (Integer)node2.data) {
+ node1 = node1.next;
+ } else if((Integer)node1.data > (Integer)node2.data) {
+ node2 = node2.next;
+ } else {
+ intersection.add(node1.data);
+ node1 = node1.next;
+ node2 = node2.next;
+ }
+ }
+
+ return intersection;
+ }
}
diff --git a/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LinkListTest.java b/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LinkListTest.java
index b1bfc6f1b8..508eaba5f9 100644
--- a/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LinkListTest.java
+++ b/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LinkListTest.java
@@ -19,6 +19,8 @@ public void init() {
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
+ linkedList.add(4);
+ linkedList.add(5);
}
@Test
@@ -78,4 +80,104 @@ public void testIterator() {
}
Assert.assertArrayEquals(new Object[]{}, linkedList.toArray());
}
+
+ @Test
+ public void testReverse() {
+ linkedList.reverse();
+ Assert.assertArrayEquals(new Object[]{3, 2, 1}, linkedList.toArray());
+ }
+
+ @Test
+ public void testRemoveFirstHalf() {
+ linkedList.removeFirstHalf();
+ Assert.assertArrayEquals(new Object[]{2, 3}, linkedList.toArray());
+ }
+
+ @Test
+ public void testRangeRemove() {
+ linkedList.remove(1, 4);
+ Assert.assertArrayEquals(new Object[]{1}, linkedList.toArray());
+ }
+
+ @Test
+ public void testGetElements() {
+ LinkedList sub = new LinkedList();
+ sub.add(1);
+ sub.add(3);
+ sub.add(4);
+ int[] result = linkedList.getElements(sub);
+ Assert.assertArrayEquals(new int[]{2, 4, 5}, result);
+ }
+
+ @Test
+ public void testSubtract() {
+ LinkedList sub = new LinkedList();
+ sub.add(1);
+ sub.add(2);
+ sub.add(10);
+ linkedList.subtract(sub);
+ Assert.assertArrayEquals(new Object[]{3, 4, 5}, linkedList.toArray());
+ }
+
+ @Test
+ public void testRemoveDuplicateValues() {
+ LinkedList list = new LinkedList();
+ list.add(1);
+ list.add(2);
+ list.add(2);
+ list.add(2);
+ list.add(3);
+ list.add(3);
+ list.add(4);
+ list.add(5);
+ list.add(6);
+ list.add(6);
+ list.add(7);
+ list.add(7);
+ list.add(7);
+ list.add(7);
+ list.add(7);
+ list.removeDuplicateValues();
+ Assert.assertArrayEquals(new Object[]{1, 2, 3, 4, 5, 6, 7}, list.toArray());
+ }
+
+ @Test
+ public void testRemoveRange() {
+ LinkedList list = new LinkedList();
+ list.add(1);
+ list.add(2);
+ list.add(2);
+ list.add(3);
+ list.add(4);
+ list.add(5);
+ list.add(6);
+ list.add(7);
+ list.add(7);
+ list.add(8);
+ list.removeRange(1, 4);
+ Assert.assertArrayEquals(new Object[]{1, 4, 5, 6, 7, 7, 8}, list.toArray());
+ }
+
+ @Test
+ public void testIntersection() {
+ LinkedList list1 = new LinkedList();
+ list1.add(1);
+ list1.add(3);
+ list1.add(5);
+ list1.add(7);
+ list1.add(9);
+ LinkedList list2 = new LinkedList();
+ list2.add(3);
+ list2.add(4);
+ list2.add(5);
+ list2.add(6);
+ list2.add(7);
+ list2.add(8);
+ list2.add(10);
+ list2.add(11);
+ list2.add(12);
+ LinkedList intersection = list1.intersection(list2);
+ Assert.assertArrayEquals(new Object[]{3, 5, 7}, intersection.toArray());
+ }
+
}
diff --git a/group01/954958168/class02/LiteStruts/pom.xml b/group01/954958168/class02/LiteStruts/pom.xml
index 9a962fe54c..40ba7c66b6 100644
--- a/group01/954958168/class02/LiteStruts/pom.xml
+++ b/group01/954958168/class02/LiteStruts/pom.xml
@@ -8,11 +8,6 @@
lite-struts
1.0.0-SNAPSHOT
-
- UTF-8
- 1.8
-
-
junit
@@ -29,6 +24,19 @@
commons-lang3
3.5
-
+
+
+
+ liteStruts
+
+ true
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
\ No newline at end of file
diff --git a/group01/954958168/class03/MultiThreadDownload/pom.xml b/group01/954958168/class03/MultiThreadDownload/pom.xml
new file mode 100644
index 0000000000..4d94b30e33
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/pom.xml
@@ -0,0 +1,32 @@
+
+
+ 4.0.0
+
+ com.aaront.exercise
+ multithread-download
+ 1.0.0-SNAPSHOT
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+
+ multiThreadDownload
+
+ true
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java
new file mode 100644
index 0000000000..8dcf538f42
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java
@@ -0,0 +1,32 @@
+package com.aaront.exercise;
+
+import com.aaront.exercise.api.Connection;
+
+import java.io.IOException;
+
+public class DownloadThread extends Thread {
+
+ Connection conn;
+ int startPos;
+ int endPos;
+ byte[] content;
+
+ public DownloadThread(Connection conn, int startPos, int endPos) {
+
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+
+ public void run() {
+ try {
+ content = conn.read(startPos, endPos);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public byte[] getContent() {
+ return this.content;
+ }
+}
\ No newline at end of file
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java
new file mode 100644
index 0000000000..128292ea8e
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java
@@ -0,0 +1,90 @@
+package com.aaront.exercise;
+
+
+import com.aaront.exercise.api.Connection;
+import com.aaront.exercise.api.ConnectionManager;
+import com.aaront.exercise.api.DownloadListener;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FileDownloader {
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+
+ public FileDownloader(String _url) {
+ this.url = _url;
+
+ }
+
+ public void execute() {
+ // 在这里实现你的代码, 注意: 需要用多线程实现下载
+ // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+ // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定)
+ // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
+ // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
+ // 具体的实现思路:
+ // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度
+ // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
+ // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
+ // 3. 把byte数组写入到文件中
+ // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+
+ Connection conn = cm.open(this.url);
+ int length = conn.getContentLength();
+ conn.close();
+ List threads = new ArrayList<>();
+ int i;
+ for (i = 0; i < 3; i++) {
+ DownloadThread thread = new DownloadThread(cm.open(this.url), i * (length / 3), (i + 1) * (length / 3) - 1);
+ threads.add(thread);
+ thread.start();
+ }
+ if (i * (length / 3) < length) {
+ DownloadThread thread = new DownloadThread(cm.open(this.url), i * (length / 3), length - 1);
+ threads.add(thread);
+ thread.start();
+ }
+
+ try {
+ for (DownloadThread thread : threads) {
+ thread.join();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ try (FileOutputStream fos = new FileOutputStream(new File("temp.jpg"))) {
+ for(DownloadThread thread : threads) {
+ fos.write(thread.getContent());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ this.listener.notifyFinished();
+ }
+
+ public void setListener(DownloadListener listener) {
+ this.listener = listener;
+ }
+
+ public void setConnectionManager(ConnectionManager ucm) {
+ this.cm = ucm;
+ }
+
+ public DownloadListener getListener() {
+ return this.listener;
+ }
+
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java
new file mode 100644
index 0000000000..6f75b3cd6c
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java
@@ -0,0 +1,41 @@
+package com.aaront.exercise;
+
+import com.aaront.exercise.api.ConnectionManager;
+import com.aaront.exercise.impl.ConnectionManagerImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FileDownloaderTest {
+ boolean downloadFinished = false;
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testDownload() {
+ String url = "http://localhost:8080/test.jpg";
+ FileDownloader downloader = new FileDownloader(url);
+ ConnectionManager cm = new ConnectionManagerImpl();
+ downloader.setConnectionManager(cm);
+ downloader.setListener(() -> downloadFinished = true);
+ downloader.execute();
+
+ // 等待多线程下载程序执行完毕
+ while (!downloadFinished) {
+ try {
+ System.out.println("还没有下载完成,休眠五秒");
+ //休眠5秒
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("下载完成!");
+ }
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/Connection.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/Connection.java
new file mode 100644
index 0000000000..64e0573bf5
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/Connection.java
@@ -0,0 +1,26 @@
+package com.aaront.exercise.api;
+
+import java.io.IOException;
+
+public interface Connection {
+ /**
+ * 给定开始和结束位置, 读取数据, 返回值是字节数组
+ *
+ * @param startPos 开始位置, 从0开始
+ * @param endPos 结束位置
+ * @return
+ */
+ public byte[] read(int startPos, int endPos) throws IOException;
+
+ /**
+ * 得到数据内容的长度
+ *
+ * @return
+ */
+ public int getContentLength();
+
+ /**
+ * 关闭连接
+ */
+ public void close();
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/ConnectionException.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/ConnectionException.java
new file mode 100644
index 0000000000..d70dffce34
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/ConnectionException.java
@@ -0,0 +1,16 @@
+package com.aaront.exercise.api;
+
+public class ConnectionException extends RuntimeException {
+
+ public ConnectionException(String message) {
+ super(message);
+ }
+
+ public ConnectionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ConnectionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/ConnectionManager.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/ConnectionManager.java
new file mode 100644
index 0000000000..7d7e027b02
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.aaront.exercise.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/DownloadListener.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/DownloadListener.java
new file mode 100644
index 0000000000..3a1defa2ca
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.aaront.exercise.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..5ad971c7c3
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java
@@ -0,0 +1,42 @@
+package com.aaront.exercise.impl;
+
+import com.aaront.exercise.api.Connection;
+import com.aaront.exercise.api.ConnectionException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class ConnectionImpl implements Connection {
+
+ private FileInputStream fis;
+ private File file;
+
+ public ConnectionImpl(String source) throws FileNotFoundException {
+ file = new File(getClass().getClassLoader().getResource(source).getFile());
+ fis = new FileInputStream(file);
+ }
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+ fis.skip(startPos);
+ byte[] content = new byte[endPos - startPos + 1];
+ fis.read(content, 0, content.length);
+ return content;
+ }
+
+ @Override
+ public int getContentLength() {
+ return (int)file.length();
+ }
+
+ @Override
+ public void close() {
+ try {
+ fis.close();
+ } catch (IOException e) {
+ throw new ConnectionException("连接关闭失败");
+ }
+ }
+}
\ No newline at end of file
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..a80c293176
--- /dev/null
+++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java
@@ -0,0 +1,28 @@
+package com.aaront.exercise.impl;
+
+import com.aaront.exercise.api.Connection;
+import com.aaront.exercise.api.ConnectionException;
+import com.aaront.exercise.api.ConnectionManager;
+
+import java.io.FileNotFoundException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+ try {
+ return new ConnectionImpl(parse(url));
+ } catch (FileNotFoundException e) {
+ throw new ConnectionException("创建连接失败");
+ }
+ }
+
+ private String parse(String url) {
+ String pattern = "(http|https)://[a-zA-Z0-9]+:[0-9]+/([a-zA-Z0-9.]+)";
+ Matcher compile = Pattern.compile(pattern).matcher(url);
+ if(!compile.matches()) throw new ConnectionException("资源url不合法");
+ return compile.group(2);
+ }
+}
diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg b/group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg
new file mode 100644
index 0000000000..0eb7a002d8
Binary files /dev/null and b/group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg differ