diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java"
index 8dbfe95dda..0b256f8f4a 100644
--- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java"
+++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java"
@@ -2,4 +2,12 @@
public class ConnectionException extends Exception {
+ /**
+ * 自定义异常错误
+ * @param string
+ */
+ public ConnectionException(String string) {
+
+ }
+
}
diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java"
index 4cd0b3eab1..ee55a8cec0 100644
--- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java"
+++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java"
@@ -1,5 +1,6 @@
package com.coderising.download.api;
public interface DownloadListener {
+
public void notifyFinished();
}
diff --git a/group04/1020483199/1020483199Learning/.classpath b/group04/1020483199/1020483199Learning/.classpath
index 3e0fb272a8..04cc82dc42 100644
--- a/group04/1020483199/1020483199Learning/.classpath
+++ b/group04/1020483199/1020483199Learning/.classpath
@@ -1,7 +1,7 @@
-
+
diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..ba70c84329
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.loader;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+
+public class ClassFileLoader {
+
+ private List clzPaths = new ArrayList();
+
+ public byte[] readBinaryCode(String className) {
+ /**
+ * class文件存储位置
+ */
+ String location = clzPaths.get(0);
+ File file = new File(location);
+ File[] files = file.listFiles();
+ InputStream in = null;
+ byte[] bt = null;
+
+ int size = 0;
+ for(File fileSon:files){
+ /**
+ * 判断出为class文件时
+ */
+ if(fileSon.isFile() && fileSon.getName().endsWith("EmployeeV1.class")){
+ try {
+ long length = fileSon.length();
+ bt = new byte[(int) length];
+ byte[] context = new byte[1024];
+ in = new FileInputStream(fileSon);
+ int tempbyte;
+ while((tempbyte = in.read(context)) != -1){
+ for(int i = 0;i < context.length;i++){
+ System.arraycopy(context, 0, bt, size, tempbyte);
+ }
+ size = tempbyte;
+ }
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }finally{
+ if(in != null){
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ }
+ }
+ return bt;
+ }
+
+
+ public void addClassPath(String path) {
+
+ clzPaths.add(path);
+
+ }
+
+
+
+ public String getClassPath(){
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0;i < clzPaths.size();i++){
+ if(i == clzPaths.size() - 1){
+ sb.append(clzPaths.get(i));
+ break;
+ }
+ sb.append(clzPaths.get(i)).append(";");
+
+ }
+ return sb.toString();
+ }
+
+
+
+
+
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..7c7d1bb15a
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,91 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+
+ static String path1 = "F:/myGithub/coding2017/group04/1020483199/FourthHomeWork/bin/com/coderising/jvm/test";
+ static String path2 = "C:/temp";
+
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testClassPath(){
+
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+ loader.addClassPath(path2);
+
+ String clzPath = loader.getClassPath();
+ Assert.assertEquals(path1+";"+path2,clzPath);
+
+ }
+
+ @Test
+ public void testClassFileLength() {
+
+ ClassFileLoader loader = new ClassFileLoader();
+
+ loader.addClassPath(path1);
+
+ String className = "com.coderising.jvm.test.EmployeeV1";
+
+ byte[] byteCodes = loader.readBinaryCode(className);
+ // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大
+ Assert.assertEquals(1056, byteCodes.length);
+
+ }
+
+
+ @Test
+ public void testMagicNumber(){
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+ String className = "com.coderising.jvm.test.EmployeeV1";
+ byte[] byteCodes = loader.readBinaryCode(className);
+ byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+
+
+ String acctualValue = this.byteToHexString(codes);
+
+ Assert.assertEquals("cafebabe", acctualValue);
+ }
+
+
+
+
+
+
+ private String byteToHexString(byte[] codes ){
+ StringBuffer buffer = new StringBuffer();
+ for(int i=0;i 2 > 1 > 5 > 4 > 5改变之前
+ //0 1 2 3 4 5index
+ //3 > 2 > 1 > x > 5 > 4 > 5插入之后
+ public void add(int index , Object o){
+ if(head != null){
+ int k = 0;
+ Node p = head;
+ while(k < index - 1 && p.next != null){
+ k++;
+ p = p.next;//当前p为要插入位置的前一个节点
+ }
+
+ if(p != null){
+ Node nd = new Node(o);
+ nd.next = p.next;
+ p.next = nd;
+ }
+
+ size++;
+
+ }
+ }
+ public Object get(int index){
+ if(index < 0 || index >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ Node p = head;
+ int k = 0;
+ while(k < index && p.next !=null){
+ k++;
+ p = p.next;
+ }
+ return p.data;
+ }
+ //3 > 2 > 1 > 5 > 4 > 5改变之前
+ //0 1 2 3 4 5index
+ //3 > 2 > 1 > 4 > 5插入之后
+ public Object remove(int index){
+ if(index < 0 || index >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ if(head == null){
+ return null;
+ }
+ if(index == 0){
+ head = head.next;
+ size--;
+ return head.data;
+ }else{
+ if(head != null){
+ int k = 0;
+ Node p = head;
+ while(k < index - 1 && p != null){
+ k++;
+ p = p.next;
+ }
+ Node pn = p.next;
+ if(pn != null){
+ p.next = pn.next;
+ size--;
+ return pn.data;
+ }
+
+ }
+ }
+ return null;
+ }
+
+ public int size(){
+
+ return size;
+ }
+
+ public void addFirst(Object o){
+ if(head != null){
+ Node nd = new Node(o);
+ Node first = head;
+ head = nd;
+ first = nd.next;
+ }
+ }
+ public void addLast(Object o){
+ if(head != null){
+ int k = 0;
+ Node p = head;
+ while(p.next != null && k < size - 1){
+ p = p.next;
+ k++;
+ }
+ Node newNode = new Node(o);
+ p.next = newNode;
+ }
+ }
+ public Object removeFirst(){
+ Node node = head;
+ if(head != null){
+ head = head.next;
+ }
+ return node.data;
+ }
+ public Object removeLast(){
+ Node p = head;
+ int k = 0;
+ while(p.next != null && k < size - 2){
+ k++;
+ p = p.next;
+ }
+
+ p.next = null;
+ return p.next;
+ }
+ public Iterator iterator(){
+ return null;
+ }
+
+
+ private static class Node{
+ Object data;
+ Node next;
+
+ private Node(Object o){
+ this.data = o;
+ this.next = null;
+ }
+ }
+
+ /**
+ * 把该链表逆置
+ * head head
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+ /**
+ * 长度超过1的单链表需要逆转
+ */
+ if(head == null || head.next == null){
+ return;
+ }
+ Stack st = new Stack();
+ Node currentNode = head;
+ while(currentNode != null){
+ st.push(currentNode);
+ Node nextNode = currentNode.next;
+ currentNode.next = null;//断开连接
+ currentNode = nextNode;
+ }
+
+ head = (Node) st.pop();
+ currentNode = head;
+ while(!st.isEmpty()){
+ Node nextNode = (Node) st.pop();
+ currentNode.next = nextNode;
+ currentNode = nextNode;
+ }
+ }
+
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+ int num = size / 2;
+ for(int i = 0; i < num; i++){
+ removeFirst();
+ }
+ }
+
+ /**
+ * 从第i个元素开始,删除length个元素 ,注意i从0开始
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length){
+ if(i < 0 || i >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ int len = size - i >= length ? length : size - i;
+ int k = 0;
+ while(k < len){
+ remove(i);
+ k++;
+ }
+
+ }
+ /**
+ * 假定当前链表和listB均包含已升序排列的整数
+ * 从当前链表中取出那些listB所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){
+ int[] newList = new int[list.size()];
+ for(int i = 0;i < list.size(); i++){
+ newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString());
+ }
+ return newList;
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在listB中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+ for(int j = 0;j < list.size();j++){
+ this.remove(list.get(j));
+ }
+
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+ if(head == null){
+ throw new RuntimeException("LinkedList is null");
+
+ }
+ Node currentNode = head;
+ Node preNode = head;
+ while(currentNode.next != null){
+ currentNode = currentNode.next;
+ Object data = preNode.data;
+ while(currentNode.data == data){
+ if(currentNode.next == null){
+ preNode.next = null;
+ break;
+ }
+ preNode.next = currentNode.next;
+ size--;
+ currentNode = currentNode.next;
+ if(currentNode == null){
+ break;
+ }
+ }
+ preNode = preNode.next;
+ }
+ }
+ /**
+ * 传入删除数据节点
+ */
+ public void remove(Object obj){
+ if(head == null){
+ throw new RuntimeException("linkedlist is nuull");
+
+ }
+ if(head.data.equals(obj)){
+ head = head.next;
+ size--;
+ }else{
+ Node pre = head;
+ Node currentNode = head.next;
+ while(currentNode != null){
+ if(currentNode.data.equals(obj)){
+ pre.next = currentNode.next;
+ size--;
+ }
+ pre = pre.next;
+ currentNode = currentNode.next;
+ }
+ }
+ }
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+ Node node = head;
+ int start = -1;
+ int end = -1;
+ int i = 0;
+ while(node != null){
+ if((Integer)node.data <= min){
+ start = i;
+ }
+ if((Integer)node.data >= max){
+ end = i;
+ break;
+ }
+ node = node.next;
+ i++;
+ }
+ if(start == -1){
+ start = 0;
+ }
+ if(end == -1){
+ end = size;
+ }
+ this.remove(start+1, end-start-1);
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection(LinkedList list){
+ if(list == null){
+ return null;
+ }
+
+ LinkedList newList = new LinkedList();
+ int fi = 0;
+ int se = 0;
+ while(fi < this.size && se < list.size()){
+ int val1 = (Integer) this.get(fi);
+ int val2 = (Integer) list.get(se);
+ if(val1 == val2){
+ newList.add(val1);
+ fi++;
+ se++;
+ }else if(val1 < val2){
+ fi++;
+ }else{
+ se++;
+ }
+
+ }
+ return newList;
+ }
+
+ public static void main(String[] args) {
+ LinkedList linkedList = new LinkedList();
+ linkedList.add(11);
+ linkedList.add(22);
+ linkedList.add(33);
+ linkedList.add(44);
+ linkedList.add(55);
+ linkedList.reverse();
+ for(int i = 0; i < linkedList.size; i++){
+ System.out.println(linkedList.get(i));
+ }
+ }
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java
new file mode 100644
index 0000000000..55ff205b5d
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java
@@ -0,0 +1,9 @@
+package com.coding.basic.linkedList;
+
+public interface List {
+ public void add(Object o);
+ public void add(int index, Object o);
+ public Object get(int index);
+ public Object remove(int index);
+ public int size();
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..e5ddb476a6
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,96 @@
+package com.coderising.array;
+
+public class ArrayUtil {
+
+ /**
+ * 给定一个整形数组a , 对该数组的值进行置换
+ 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7]
+ 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+ * @param origin
+ * @return
+ */
+ public void reverseArray(int[] origin){
+
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public int[] removeZero(int[] oldArray){
+ return null;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的
+ * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public int[] merge(int[] array1, int[] array2){
+ return null;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+ return null;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列
+ * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13]
+ * max = 1, 则返回空数组 []
+ * @param max
+ * @return
+ */
+ public int[] fibonacci(int max){
+ return null;
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public int[] getPrimes(int max){
+ return null;
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public int[] getPerfectNumbers(int max){
+ return null;
+ }
+
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public String join(int[] array, String seperator){
+ return null;
+ }
+
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..d16eca2319
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,42 @@
+package com.coderising.download;
+
+
+
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+
+ private Connection conn;
+ private int startPos;
+ private int endPos;
+ private String filePath;
+ private CyclicBarrier barrier;
+
+ public DownloadThread(Connection conn, int startPos, int endPos,String filePath,CyclicBarrier barrier){
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ this.filePath = filePath;
+ this.barrier = barrier;
+ }
+ public void run(){
+ try {
+ System.out.println("线程" + this.getName() + "开始下载. startPos:" + startPos + "; endPos:" + endPos);
+ byte[] buffer = conn.read(startPos, endPos);
+ RandomAccessFile ra = new RandomAccessFile(filePath, "rw");
+ ra.seek(startPos);
+ ra.write(buffer);
+ //关闭流
+ ra.close();
+ conn.close();
+ barrier.await();
+ System.out.println("线程" + this.getName() + "下载完成.");
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..c6cdf3fc4a
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,139 @@
+package com.coderising.download;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+
+import org.junit.internal.runners.statements.RunAfters;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+
+ private String url;
+
+ private String localFile;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+ private final static int thread_count = 3;
+
+ public FileDownloader(String _url,String localFile) {
+ this.url = _url;
+ this.localFile = localFile;
+ }
+
+ 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方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+ CyclicBarrier barrier = new CyclicBarrier(thread_count, new Runnable() {
+
+ @Override
+ public void run() {
+ listener.notifyFinished();
+ }
+ });
+ Connection conn = null;
+ try {
+
+ conn = cm.open(this.url);
+
+ int length = conn.getContentLength();
+
+ createPlaceHolderFile(this.localFile,length);
+
+ int[] [] ranges = allowcateDownloadRange(thread_count,length);
+
+ for(int i = 0; i < thread_count; i++){
+
+ DownloadThread thread= new DownloadThread(conn, ranges[i][0], ranges[i][1], localFile, barrier);
+
+ thread.start();
+
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }finally{
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+
+
+
+ }
+
+ private int[][] allowcateDownloadRange(int threadCount, int length) {
+ int[][] ranges = new int[thread_count][2];
+
+ int eachThreadSize = length / threadCount;
+
+ int left = length % threadCount;
+
+ for(int i = 0 ; i < thread_count;i++){
+ int startPos = i * eachThreadSize;
+
+ int endPos = (i+1) * eachThreadSize - 1;
+
+ if((i==thread_count -1)){
+ endPos += left;
+ }
+
+ ranges[i][0] = startPos;
+ ranges[i][1] = endPos;
+ }
+
+ return ranges;
+ }
+
+ private void createPlaceHolderFile(String localfile, int length) throws IOException {
+ RandomAccessFile file = new RandomAccessFile(localfile, "rw");
+ for(int i = 0;i < length ; i++){
+ file.write(0);
+ }
+ file.close();
+ }
+
+ 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/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..7393f57040
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,90 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+ boolean downloadFinished = false;
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testContentLength() throws Exception{
+ ConnectionManager connMan = new ConnectionManagerImpl();
+ Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");
+ Assert.assertEquals(35470, conn.getContentLength());
+ }
+
+ @Test
+ public void testRead() throws Exception{
+
+ ConnectionManager connMan = new ConnectionManagerImpl();
+ Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");
+
+ byte[] data = conn.read(0, 35469);
+
+ Assert.assertEquals(35470, data.length);
+
+ data = conn.read(0, 1023);
+
+ Assert.assertEquals(1024, data.length);
+
+ data = conn.read(1024, 2023);
+
+ Assert.assertEquals(1000, data.length);
+
+
+ // 测试不充分,没有断言内容是否正确
+ }
+
+ @Test
+ public void testDownload() {
+
+ String url = "http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg";
+
+ FileDownloader downloader = new FileDownloader(url, "F:/picture/a.png");
+
+
+ ConnectionManager cm = new ConnectionManagerImpl();
+ downloader.setConnectionManager(cm);
+
+ downloader.setListener(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ 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/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.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/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..105f00f03a
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,13 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+ /**
+ * 自定义异常错误
+ * @param string
+ */
+ public ConnectionException(Exception e) {
+ super(e);
+ }
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..7b51663ff9
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,6 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+
+ public void notifyFinished();
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..dcaf5883fa
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,89 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+
+class ConnectionImpl implements Connection {
+
+ URL url;
+ static final int BUFFER_SIZE = 1024;
+
+ ConnectionImpl(String _url) throws ConnectionException{
+ try {
+ url = new URL(_url);
+ } catch (MalformedURLException e) {
+ throw new ConnectionException(e);
+ }
+ }
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+
+
+ HttpURLConnection httpConn = (HttpURLConnection)url.openConnection();
+
+ httpConn.setRequestProperty("Range", "bytes=" + startPos + "-"
+ + endPos);
+
+ InputStream is = httpConn.getInputStream();
+
+ //is.skip(startPos);
+
+ byte[] buff = new byte[BUFFER_SIZE];
+
+ int totalLen = endPos - startPos + 1;
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ while(baos.size() < totalLen){
+
+ int len = is.read(buff);
+ if (len < 0) {
+ break;
+ }
+ baos.write(buff,0, len);
+ }
+
+
+ if(baos.size() > totalLen){
+ byte[] data = baos.toByteArray();
+ return Arrays.copyOf(data, totalLen);
+ }
+
+ return baos.toByteArray();
+ }
+
+ @Override
+ public int getContentLength() {
+
+ URLConnection con;
+ try {
+ con = url.openConnection();
+
+ return con.getContentLength();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return -1;
+
+
+ }
+
+ @Override
+ public void close() {
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..3af9b21485
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,17 @@
+package com.coderising.download.impl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+ return new ConnectionImpl(url);
+ }
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..dcdbe226ed
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..6df190d484
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java
@@ -0,0 +1,37 @@
+package com.coderising.litestruts;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+
+ public static View runAction(String actionName, Map parameters) {
+
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+
+
+ return null;
+ }
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..b8c81faf3c
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..3fe0a702d4
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java
@@ -0,0 +1,27 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+
+ public void setJsp(String jsp) {
+ this.jsp = jsp;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map parameters) {
+ this.parameters = parameters;
+ }
+
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java
new file mode 100644
index 0000000000..1f185736f9
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class ArrayList implements List {
+
+ private int size = 0;
+
+ private Object[] elementData = new Object[100];
+
+ public void add(Object o){
+
+ }
+ public void add(int index, Object o){
+
+ }
+
+ public Object get(int index){
+ return null;
+ }
+
+ public Object remove(int index){
+ return null;
+ }
+
+ public int size(){
+ return -1;
+ }
+
+ public Iterator iterator(){
+ return null;
+ }
+
+}
diff --git a/group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java
similarity index 100%
rename from group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java
rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java
diff --git a/group04/120549547/base/src/com/coding/basic/Iterator.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java
similarity index 100%
rename from group04/120549547/base/src/com/coding/basic/Iterator.java
rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java
new file mode 100644
index 0000000000..7b10ffb8b6
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java
@@ -0,0 +1,374 @@
+package com.coding.basic;
+
+import java.util.Stack;
+
+public class LinkedList implements List {
+ private int size;
+
+ private Node head;
+
+ public LinkedList(){
+ size = 0;
+
+ head = null;
+ }
+
+ public void add(Object o){
+ Node nd = new Node(o);
+ if(head == null){
+ head = nd;
+ }else{
+ Node p = head;
+ while(p.next != null){
+ p = p.next;
+ }
+ p.next = nd;
+ }
+ size ++;
+
+ }
+ //3 > 2 > 1 > 5 > 4 > 5改变之前
+ //0 1 2 3 4 5index
+ //3 > 2 > 1 > x > 5 > 4 > 5插入之后
+ public void add(int index , Object o){
+ if(head != null){
+ int k = 0;
+ Node p = head;
+ while(k < index - 1 && p.next != null){
+ k++;
+ p = p.next;//当前p为要插入位置的前一个节点
+ }
+
+ if(p != null){
+ Node nd = new Node(o);
+ nd.next = p.next;
+ p.next = nd;
+ }
+
+ size++;
+
+ }
+ }
+ public Object get(int index){
+ if(index < 0 || index >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ Node p = head;
+ int k = 0;
+ while(k < index && p.next !=null){
+ k++;
+ p = p.next;
+ }
+ return p.data;
+ }
+ //3 > 2 > 1 > 5 > 4 > 5改变之前
+ //0 1 2 3 4 5index
+ //3 > 2 > 1 > 4 > 5插入之后
+ public Object remove(int index){
+ if(index < 0 || index >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ if(head == null){
+ return null;
+ }
+ if(index == 0){
+ head = head.next;
+ size--;
+ return head.data;
+ }else{
+ if(head != null){
+ int k = 0;
+ Node p = head;
+ while(k < index - 1 && p != null){
+ k++;
+ p = p.next;
+ }
+ Node pn = p.next;
+ if(pn != null){
+ p.next = pn.next;
+ size--;
+ return pn.data;
+ }
+
+ }
+ }
+ return null;
+ }
+
+ public int size(){
+
+ return size;
+ }
+
+ public void addFirst(Object o){
+ if(head != null){
+ Node nd = new Node(o);
+ Node first = head;
+ head = nd;
+ first = nd.next;
+ }
+ }
+ public void addLast(Object o){
+ if(head != null){
+ int k = 0;
+ Node p = head;
+ while(p.next != null && k < size - 1){
+ p = p.next;
+ k++;
+ }
+ Node newNode = new Node(o);
+ p.next = newNode;
+ }
+ }
+ public Object removeFirst(){
+ Node node = head;
+ if(head != null){
+ head = head.next;
+ }
+ return node.data;
+ }
+ public Object removeLast(){
+ Node p = head;
+ int k = 0;
+ while(p.next != null && k < size - 2){
+ k++;
+ p = p.next;
+ }
+
+ p.next = null;
+ return p.next;
+ }
+ public Iterator iterator(){
+ return null;
+ }
+
+
+ private static class Node{
+ Object data;
+ Node next;
+
+ private Node(Object o){
+ this.data = o;
+ this.next = null;
+ }
+ }
+
+ /**
+ * 把该链表逆置
+ * head head
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+ /**
+ * 长度超过1的单链表需要逆转
+ */
+ if(head == null || head.next == null){
+ return;
+ }
+ Stack st = new Stack();
+ Node currentNode = head;
+ while(currentNode != null){
+ st.push(currentNode);
+ Node nextNode = currentNode.next;
+ currentNode.next = null;//断开连接
+ currentNode = nextNode;
+ }
+
+ head = (Node) st.pop();
+ currentNode = head;
+ while(!st.isEmpty()){
+ Node nextNode = (Node) st.pop();
+ currentNode.next = nextNode;
+ currentNode = nextNode;
+ }
+ }
+
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+ int num = size / 2;
+ for(int i = 0; i < num; i++){
+ removeFirst();
+ }
+ }
+
+ /**
+ * 从第i个元素开始,删除length个元素 ,注意i从0开始
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length){
+ if(i < 0 || i >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ int len = size - i >= length ? length : size - i;
+ int k = 0;
+ while(k < len){
+ remove(i);
+ k++;
+ }
+
+ }
+ /**
+ * 假定当前链表和listB均包含已升序排列的整数
+ * 从当前链表中取出那些listB所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){
+ int[] newList = new int[list.size()];
+ for(int i = 0;i < list.size(); i++){
+ newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString());
+ }
+ return newList;
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在listB中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+ for(int j = 0;j < list.size();j++){
+ this.remove(list.get(j));
+ }
+
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+ if(head == null){
+ throw new RuntimeException("LinkedList is null");
+
+ }
+ Node currentNode = head;
+ Node preNode = head;
+ while(currentNode.next != null){
+ currentNode = currentNode.next;
+ Object data = preNode.data;
+ while(currentNode.data == data){
+ if(currentNode.next == null){
+ preNode.next = null;
+ break;
+ }
+ preNode.next = currentNode.next;
+ size--;
+ currentNode = currentNode.next;
+ if(currentNode == null){
+ break;
+ }
+ }
+ preNode = preNode.next;
+ }
+ }
+ /**
+ * 传入删除数据节点
+ */
+ public void remove(Object obj){
+ if(head == null){
+ throw new RuntimeException("linkedlist is nuull");
+
+ }
+ if(head.data.equals(obj)){
+ head = head.next;
+ size--;
+ }else{
+ Node pre = head;
+ Node currentNode = head.next;
+ while(currentNode != null){
+ if(currentNode.data.equals(obj)){
+ pre.next = currentNode.next;
+ size--;
+ }
+ pre = pre.next;
+ currentNode = currentNode.next;
+ }
+ }
+ }
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+ Node node = head;
+ int start = -1;
+ int end = -1;
+ int i = 0;
+ while(node != null){
+ if((Integer)node.data <= min){
+ start = i;
+ }
+ if((Integer)node.data >= max){
+ end = i;
+ break;
+ }
+ node = node.next;
+ i++;
+ }
+ if(start == -1){
+ start = 0;
+ }
+ if(end == -1){
+ end = size;
+ }
+ this.remove(start+1, end-start-1);
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection(LinkedList list){
+ if(list == null){
+ return null;
+ }
+
+ LinkedList newList = new LinkedList();
+ int fi = 0;
+ int se = 0;
+ while(fi < this.size && se < list.size()){
+ int val1 = (Integer) this.get(fi);
+ int val2 = (Integer) list.get(se);
+ if(val1 == val2){
+ newList.add(val1);
+ fi++;
+ se++;
+ }else if(val1 < val2){
+ fi++;
+ }else{
+ se++;
+ }
+
+ }
+ return newList;
+ }
+
+ public static void main(String[] args) {
+ LinkedList linkedList = new LinkedList();
+ linkedList.add(11);
+ linkedList.add(22);
+ linkedList.add(33);
+ linkedList.add(44);
+ linkedList.add(55);
+ linkedList.reverse();
+ for(int i = 0; i < linkedList.size; i++){
+ System.out.println(linkedList.get(i));
+ }
+ }
+}
diff --git a/group12/446031103/src/com/coding/basic/List.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java
similarity index 100%
rename from group12/446031103/src/com/coding/basic/List.java
rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java
new file mode 100644
index 0000000000..36e516e266
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java
@@ -0,0 +1,19 @@
+package com.coding.basic;
+
+public class Queue {
+
+ public void enQueue(Object o){
+ }
+
+ public Object deQueue(){
+ return null;
+ }
+
+ public boolean isEmpty(){
+ return false;
+ }
+
+ public int size(){
+ return -1;
+ }
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java
new file mode 100644
index 0000000000..a25d5b8024
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java
@@ -0,0 +1,22 @@
+package com.coding.basic;
+
+public class Stack {
+ private ArrayList elementData = new ArrayList();
+
+ public void push(Object o){
+ }
+
+ public Object pop(){
+ return null;
+ }
+
+ public Object peek(){
+ return null;
+ }
+ public boolean isEmpty(){
+ return false;
+ }
+ public int size(){
+ return -1;
+ }
+}
diff --git a/group04/120549547/base/buil.bat b/group04/120549547/base/buil.bat
deleted file mode 100644
index 7164a42ac0..0000000000
--- a/group04/120549547/base/buil.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-javac -sourcepath src -d classes -encoding utf-8 src\com\coding\basic\*.java
-
-java -cp classes com.coding.basic.Main
-
-pause
\ No newline at end of file
diff --git a/group04/120549547/base/src/com/coding/basic/ArrayList.java b/group04/120549547/base/src/com/coding/basic/ArrayList.java
deleted file mode 100644
index 56e7aa4c26..0000000000
--- a/group04/120549547/base/src/com/coding/basic/ArrayList.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.coding.basic;
-import java.util.Arrays;
-
-public class ArrayList implements List {
- /*默认数组容量*/
- public static final int DEFAULT_CAPCATITY = 10;
-
- /*数组元素个数*/
- private int size;
-
- private Object[] elementData;
-
- public ArrayList(){
- this(DEFAULT_CAPCATITY);
- }
-
- public ArrayList(int capacity){
- if (capacity<0 || capacity>Integer.MAX_VALUE)
- throw new IllegalArgumentException("非法容量: " + capacity);
- elementData = new Object[capacity];
- }
-
-
- public void add(Object o){
- /*判断是否需要扩容*/
- ensureCapacity(size + 1);
- elementData[size++] = o;
- }
-
- public void add(int index, Object o){
- checkIndex(index);
- /*判断是否需要扩容*/
- ensureCapacity(size + 1);
- /*将index->size的元素依次向右移一个位置*/
- System.arraycopy(elementData, index, elementData, index+1, size-index);
- /*插入o的值*/
- elementData[index] = o;
- size++;
- }
-
-
- public Object get(int index){
-
- checkIndex(index);
- return elementData[index];
- }
-
- public Object remove(int index){
-
- checkIndex(index);
- Object value = elementData[index];
- /*将index+1 -> size的元素依次向左移一个位置*/
- System.arraycopy(elementData,index+1, elementData, index, size-index-1);
- elementData[--size]=null; //释放最后一个元素,同时size减一;
- return value;
- }
-
- public int size(){
- return this.size;
- }
-
- public Iterator iterator(){
- return null;
- }
- /* 确认容量是否足够,也可以直接调用手动扩容*/
- public void ensureCapacity(int minCapacity){
- int oldCapacity = elementData.length;
- /*容量不足需要扩容*/
- if(oldCapacity < minCapacity){
- int newCapacity = oldCapacity * 2; //扩大2倍
- if (newCapacity < minCapacity){
- newCapacity = minCapacity; //扩容后仍不足,取最大值
- }
- System.out.println("数据扩容至: " + newCapacity);
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
-
- }
-
- private void checkIndex(int index){
- if (index<0 || index>= size)
- throw new IndexOutOfBoundsException ("index非法: " + index);
- }
- @Override
- public String toString(){
-
- StringBuffer sb = new StringBuffer("");
- for(int i=0; i ");
- }
- return sb.toString();
- }
-}
diff --git a/group04/120549547/base/src/com/coding/basic/LinkedList.java b/group04/120549547/base/src/com/coding/basic/LinkedList.java
deleted file mode 100644
index edfbcc1007..0000000000
--- a/group04/120549547/base/src/com/coding/basic/LinkedList.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package com.coding.basic;
-
-public class LinkedList implements List {
-
- private Node head;
- private int size;
- /*创建一个带头节点的单链表*/
- public LinkedList(){
- head = new Node(null);
- }
-
- /*添加一个元素(尾插法)*/
- public void add(Object o){
-
- Node node = new Node(o);
- Node pos = head;
- //找到最后一个元素位置
- while(pos.next != null){
- pos = pos.next;
- }
- pos.next = node;
- size++;
-
- }
-
- /*在index位置插入*/
- public void add(int index , Object o){
- //判断索引是否合法
- checkIndex(index);
- Node node = new Node(o);
- Node pos = head;
- //找到插入位置
- while(index-- != 0){
- pos = pos.next;
- }
- node.next = pos.next;
- pos.next = node;
- size++;
-
- }
- public Object get(int index){
- checkIndex(index);
- if(this.isEmpty()){
- throw new IllegalArgumentException ("链表为空");
- }
- Node pos = head.next; //pos指向要获取的节点
- while(index-- !=0){
- pos = pos.next;
- }
-
- return pos.data;
- }
- public Object remove(int index){
- checkIndex(index);
- if(this.isEmpty()){
- throw new IllegalArgumentException ("链表为空");
- }
-
- Node pos = head; //pos指向要删除的前一个结点
- while(index-- != 0){
- pos = pos.next;
- }
- Node value = pos.next; //要删除的节点
- pos.next = value.next;
- size--;
- return value.data;
-
-
- }
-
- public int size(){
- return size;
- }
-
- public void addFirst(Object o){
-
- }
- public void addLast(Object o){
- this.add(o);
- }
- public Object removeFirst(){
- if(this.isEmpty()){
- throw new IllegalArgumentException ("链表为空");
- }
- return remove(0);
- }
- public Object removeLast(){
- if(this.isEmpty()){
- throw new IllegalArgumentException ("链表为空");
- }
- return remove(size-1);
- }
-
- public boolean isEmpty(){
- return size == 0;
- }
- public Iterator iterator(){
- return null;
- }
-
- private void checkIndex(int index){
- if (index<0 || index>=size ){
- throw new IllegalArgumentException ("index不合法: " + index );
- }
- }
-
- @Override
- public String toString(){
-
- StringBuffer sb = new StringBuffer("");
- for(int i=0; i ");
- }
- return sb.toString();
- }
-
- private static class Node{
- public Object data;
- public Node next;
-
- public Node(Object data){
- this.data = data;
- this.next = null;
- }
-
- }
-}
diff --git a/group04/120549547/base/src/com/coding/basic/Main.java b/group04/120549547/base/src/com/coding/basic/Main.java
deleted file mode 100644
index de8a0b0990..0000000000
--- a/group04/120549547/base/src/com/coding/basic/Main.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.coding.basic;
-import com.coding.basic.*;
-
-class Main{
-
- public static void main(String[] args){
- System.out.println("数组测试开始");
- ArrayListTest();
- System.out.println("----------------分割线----------------");
- System.out.println("链表测试开始");
- LinkedListTest();
- System.out.println("----------------分割线----------------");
- System.out.println("栈测试开始");
- StatckTest();
- System.out.println("----------------分割线----------------");
- System.out.println("队测试开始");
- QueueTest();
- }
-
- public static void ArrayListTest(){
- ArrayList list = new ArrayList(2);
- list.add("HelloBobi0");
- list.add("HelloBobi1");
- list.add("HelloBobi2");
- list.add("HelloBobi3");
- list.add("HelloBobi4");
- list.add("HelloBobi5");
- System.out.println((String)list.get(0));
- System.out.println((String)list.get(4));
- list.add(3, "Hei Man");
- list.remove(5);
- System.out.println(list);
- System.out.println("size:=" + list.size());
- }
-
- public static void LinkedListTest(){
- LinkedList ll = new LinkedList();
-
-
- ll.add("SingleDog0");
- ll.add("SingleDog1");
- ll.add("SingleDog2");
- ll.add("SingleDog3");
- ll.add("SingleDog4");
- ll.add("SingleDog5");
-
- System.out.println((String)(ll.get(1)));
- System.out.println(ll);
- System.out.println("size:=" + ll.size());
- ll.remove(0);
- ll.removeFirst();
- ll.removeLast();
- System.out.println(ll);
- }
-
- public static void StatckTest(){
- Stack stack = new Stack();
- stack.push("虾师傅0");
- stack.push("虾师傅1");
- stack.push("虾师傅2");
- stack.push("虾师傅3");
- stack.push("虾师傅4");
-
- stack.pop();
- System.out.println(stack.peek());
- System.out.println(stack);
-
- }
- public static void QueueTest(){
- Queue queue = new Queue();
- queue.enQueue("龙师傅0");
- queue.enQueue("龙师傅1");
- queue.enQueue("龙师傅2");
- queue.enQueue("龙师傅3");
- queue.enQueue("龙师傅4");
-
- System.out.println(queue.deQueue());
- System.out.println(queue.deQueue());
- System.out.println(queue.deQueue());
- System.out.println(queue.deQueue());
- System.out.println(queue.size());
-
-
- }
-}
\ No newline at end of file
diff --git a/group04/120549547/base/src/com/coding/basic/Queue.java b/group04/120549547/base/src/com/coding/basic/Queue.java
deleted file mode 100644
index 8f86f7492c..0000000000
--- a/group04/120549547/base/src/com/coding/basic/Queue.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.coding.basic;
-import com.coding.basic.*;
-public class Queue {
- private LinkedList list;
-
- public Queue(){
- list = new LinkedList();
- }
- /*入队*/
- public void enQueue(Object o){
- list.addLast(o);
- }
-
- /*出队*/
- public Object deQueue(){
- if (isEmpty()){
- System.out.println("队空");
- }
- return list.removeFirst();
- }
-
- public boolean isEmpty(){
- return list.isEmpty();
- }
-
- public int size(){
- return list.size();
- }
-}
diff --git a/group04/120549547/base/src/com/coding/basic/Stack.java b/group04/120549547/base/src/com/coding/basic/Stack.java
deleted file mode 100644
index f7d3bba3db..0000000000
--- a/group04/120549547/base/src/com/coding/basic/Stack.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.coding.basic;
-import com.coding.basic.LinkedList;
-
-public class Stack {
- private LinkedList list;
-
- public Stack(){
- list = new LinkedList();
- }
-
- public void push(Object o){
- list.addLast(o);
- }
-
- public Object pop(){
- if(isEmpty()){
- System.out.println("栈空");
- }
- return list.removeLast();
-
- }
-
- public Object peek(){
- return list.get(list.size()-1);
- }
- public boolean isEmpty(){
- return list.isEmpty();
- }
- public int size(){
- return list.size();
- }
-
- @Override
- public String toString(){
- return list.toString();
- }
-}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java
new file mode 100644
index 0000000000..d7ac820192
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class BinaryTreeNode {
+
+ private Object data;
+ private BinaryTreeNode left;
+ private BinaryTreeNode right;
+
+ public Object getData() {
+ return data;
+ }
+ public void setData(Object data) {
+ this.data = data;
+ }
+ public BinaryTreeNode getLeft() {
+ return left;
+ }
+ public void setLeft(BinaryTreeNode left) {
+ this.left = left;
+ }
+ public BinaryTreeNode getRight() {
+ return right;
+ }
+ public void setRight(BinaryTreeNode right) {
+ this.right = right;
+ }
+
+ public BinaryTreeNode insert(Object o){
+ return null;
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java
new file mode 100644
index 0000000000..31d6470bef
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java
@@ -0,0 +1,8 @@
+package com.coding.basic;
+
+public interface Iterator {
+ boolean hasNext();
+
+ T next();
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/List.java b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java
new file mode 100644
index 0000000000..70a783968e
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java
@@ -0,0 +1,31 @@
+package com.coding.basic;
+
+public interface List{
+ int size();
+
+ boolean isEmpty();
+
+ boolean contains(Object o);
+
+ Object[] toArray();
+
+ boolean add(T o);
+
+ boolean remove(T o);
+
+ void clear();
+
+ T get(int index);
+
+ T set(int index, T o);
+
+ void add(int index, T o);
+
+ T remove(int index);
+
+ int indexOf(T o);
+
+ Iterator iterator();
+
+ void printf();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java
new file mode 100644
index 0000000000..459ec560b4
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java
@@ -0,0 +1,24 @@
+package com.coding.basic;
+
+import com.coding.basic.array.ArrayList;
+
+public class Stack {
+ private ArrayList elementData = new ArrayList();
+
+ public void push(Object o){
+ }
+
+ public Object pop(){
+ return null;
+ }
+
+ public Object peek(){
+ return null;
+ }
+ public boolean isEmpty(){
+ return false;
+ }
+ public int size(){
+ return -1;
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java
new file mode 100644
index 0000000000..6c392a3618
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java
@@ -0,0 +1,155 @@
+package com.coding.basic.array;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+import java.util.Objects;
+
+public class ArrayList implements List {
+
+ private int size;
+ private Object[] dataArray = new Object[0];
+
+ public int size() {
+ return this.size;
+ }
+
+ public boolean isEmpty() {
+ return this.size == 0;
+ }
+
+ public boolean contains(Object o) {
+ for (Object obj : dataArray) {
+ if (Objects.equals(obj, o)){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Object[] toArray() {
+ Object[] array = new Object[size];
+ System.arraycopy(dataArray, 0, array, 0, size);
+ return array;
+ }
+
+ public boolean add(T o) {
+ ensureCapacity(size+1);
+ dataArray[size] = o;
+ size++;
+ return true;
+ }
+
+
+
+ public boolean remove(T o) {
+ int index = indexOf(o);
+ if (index < 0){
+ return false;
+ }
+
+ System.arraycopy(dataArray, index + 1, dataArray, index, size - 1 - index);
+ dataArray[size - 1] = null;
+ size--;
+ return true;
+ }
+
+ public void clear() {
+ for (int i = 0; i < size; i++) {
+ dataArray[i] = null;
+ }
+ size = 0;
+ }
+ @SuppressWarnings("unchecked")
+ public T get(int index) {
+ if (index < 0 || index >= size){
+ throw new IndexOutOfBoundsException();
+ }
+
+ return (T) dataArray[index];
+ }
+
+ public T set(int index, T o) {
+ if (index < 0 || index >= size){
+ throw new IndexOutOfBoundsException();
+ }
+ dataArray[index] = o;
+ return o;
+ }
+
+ public void add(int index, T o) {
+ if (index < 0 || index > size) {
+ throw new IndexOutOfBoundsException();
+ }
+ ensureCapacity(size + 1);
+ System.arraycopy(dataArray, index, dataArray, index + 1, size - index);
+
+ dataArray[index] = o;
+
+ size++;
+ }
+
+ public T remove(int index) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException();
+ }
+ T removeData = (T) dataArray[index];
+ System.arraycopy(dataArray, index + 1, dataArray, index, size - index -1 );
+ dataArray[size - 1] = null;
+ size--;
+ return removeData;
+ }
+
+ public int indexOf(T o) {
+ for (int i = 0; i < size; i++) {
+ if (Objects.equals(o, dataArray[i])){
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public Iterator iterator() {
+ return new ArrayListIterator();
+ }
+
+ @Override
+ public void printf() {
+ for (int i = 0; i < size; i++) {
+ if (i == size - 1){
+ System.out.print(dataArray[i]);
+ }else {
+ System.out.print(dataArray[i] + "->");
+ }
+ }
+ }
+
+ private void ensureCapacity(int minCapacity) {
+ if (minCapacity > dataArray.length){
+ int newCapacity = Math.max(minCapacity, dataArray.length * 2);
+ Object[] newDataArray = new Object[newCapacity];
+ System.arraycopy(dataArray, 0, newDataArray, 0, dataArray.length);
+ dataArray = newDataArray;
+ }
+
+ }
+
+
+ private class ArrayListIterator implements Iterator {
+
+ private int pos;
+
+ @Override
+ public boolean hasNext() {
+ return pos < size();
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()){
+ return get(pos++);
+ }
+ return null;
+ }
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java
new file mode 100644
index 0000000000..411b60990b
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java
@@ -0,0 +1,269 @@
+package com.coding.basic.array;
+
+import java.util.Arrays;
+
+public class ArrayUtil {
+
+ /**
+ * 给定一个整形数组a , 对该数组的值进行置换
+ 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7]
+ 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+ * @param origin
+ * @return
+ */
+ public static void reverseArray(int[] origin){
+
+ if (origin == null || origin.length == 0){
+ return;
+ }
+
+ int temp ;
+ for (int i = 0; i < (origin.length / 2); i++) {
+ temp = origin[i];
+ origin[i] = origin[(origin.length - 1) - i];
+ origin[(origin.length - 1)- i] = temp;
+ }
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public static int[] removeZero(int[] oldArray){
+ if (oldArray == null ){
+ return null;
+ }
+
+ if (oldArray.length == 0){
+ return oldArray;
+ }
+
+ int count = 0;
+ int[] temp = new int[oldArray.length];
+
+ for (int i = 0; i < oldArray.length; i++) {
+ if (oldArray[i] != 0){
+ temp[count++] = oldArray[i];
+ }
+ }
+
+ int[] result = new int[count];
+
+ System.arraycopy(temp, 0, result, 0, count);
+ return result;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的
+ * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public static int[] merge(int[] array1, int[] array2){
+ if (array1 == null && array2 == null){
+ return null;
+ }
+
+ if (array1 == null){
+ return array2;
+ }
+
+ if (array2 == null){
+ return array1;
+ }
+
+ int length1 = array1.length;
+ int length2 = array2.length;
+ int[] temp = new int[length1 + length2];
+ int i,j,k;
+ for ( i = 0, j = 0, k = 0; i < length1 && j < length2 ;) {
+
+ if (array1[i] < array2[j]){
+ temp[k++] = array1[i++];
+ }else if (array1[i] > array2[j]){
+ temp[k++] = array2[j++];
+ }else {
+ temp[k++] = array1[i];
+ i++;
+ j++;
+ }
+ }
+
+ while (i < length1){
+ temp[k++] = array1[i++];
+ }
+
+ while (j < length2){
+ temp[k++] = array2[j++];
+ }
+ int[] result = new int[k];
+ System.arraycopy(temp, 0, result, 0, k);
+ return result;
+
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public static int[] grow(int [] oldArray, int size){
+
+ int oldSize = oldArray.length;
+ int[] newArray = new int[oldSize + size];
+
+ System.arraycopy(oldArray, 0, newArray, 0, oldSize);
+
+ return newArray;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列
+ * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13]
+ * max = 1, 则返回空数组 []
+ * @param max
+ * @return
+ */
+ public static int[] fibonacci1(int max){
+ if (max == 1){
+ return new int[0];
+ }
+
+ int[] temp = new int[max];
+ int count = 0;
+// for (int i = 1; i < max; i++) {
+// int num = fibonacci(i);
+// if (num < max){
+// temp[count++] = num;
+// }else {
+// break;
+// }
+// }
+ temp[0] = 1;
+ temp[1] = 2;
+ for (int i = 2; i < max; i++) {
+ temp[i] = temp[i-1] + temp[i-2]; //直接在数组中实现斐波那契数列
+ if (temp[i] >= max){
+ break;
+ }else {
+ count++;
+ }
+ }
+
+
+
+ return Arrays.copyOf(temp, count);
+ }
+
+ private static int fibonacci(int n){
+ if (n <= 0){
+ throw new IllegalArgumentException();
+ }
+
+ if (n == 1 || n == 2) {
+ return 1;
+ }
+
+ return fibonacci(n - 1) + fibonacci(n - 2);
+
+ }
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public static int[] getPrimes(int max){
+
+ if (max <= 2){
+ return new int[0];
+ }
+
+ int[] temp = new int[max];
+
+ int count = 0;
+ for (int i = 2; i < max; i++) {
+ int j;
+ for ( j = 2; j * j < i; j++) {
+ if (i % j == 0){
+ break;
+ }
+ }
+
+ if (j * j >= i){
+ temp[count++] = i;
+ }
+ }
+
+ return Arrays.copyOf(temp, count);
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public static int[] getPerfectNumbers(int max){
+ if ( max <= 1){
+ return new int[0];
+ }
+
+ ArrayList array = new ArrayList<>();
+ for (int i = 2; i < max; i++) {
+ int sum = 0; //存储因子和
+ for (int j = 1; j < i; j++) {
+ if (i % j == 0){
+ sum += j;
+ }
+ }
+
+ if (sum == i){
+ array.add(i);
+ }
+ }
+ int[] result = new int[array.size()];
+
+ for (int i = 0; i < array.size(); i++) {
+ result[i] = array.get(i);
+ }
+ return result;
+
+
+ }
+
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public static String join(int[] array, String seperator){
+
+ if (array == null || array.length == 0){
+ return null;
+ }
+
+ StringBuilder sb = new StringBuilder("");
+ for (int i = 0; i < array.length-1; i++) {
+ sb.append(array[i]).append(seperator);
+ }
+
+ sb.append(array[array.length-1]);
+
+ return sb.toString();
+ }
+
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..a4f2c14606
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,60 @@
+package com.coding.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+
+ private static class Node {
+
+ Node prev;
+ Node next;
+ int pageNum;
+
+ Node() {
+ }
+ }
+
+ private int capacity;
+
+
+ private Node first;// 链表头
+ private Node last;// 链表尾
+
+
+ public LRUPageFrame(int capacity) {
+
+ this.capacity = capacity;
+
+ }
+
+ /**
+ * 获取缓存中对象
+ *
+ * @param key
+ * @return
+ */
+ public void access(int pageNum) {
+
+
+ }
+
+
+
+ public String toString(){
+ StringBuilder buffer = new StringBuilder();
+ Node node = first;
+ while(node != null){
+ buffer.append(node.pageNum);
+
+ node = node.next;
+ if(node != null){
+ buffer.append(",");
+ }
+ }
+ return buffer.toString();
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..67cf36067b
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package com.coding.basic.linklist;
+
+import org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+
+ @Test
+ public void testAccess() {
+ LRUPageFrame frame = new LRUPageFrame(3);
+ frame.access(7);
+ frame.access(0);
+ frame.access(1);
+ Assert.assertEquals("1,0,7", frame.toString());
+ frame.access(2);
+ Assert.assertEquals("2,1,0", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(3);
+ Assert.assertEquals("3,0,2", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,3,2", frame.toString());
+ frame.access(4);
+ Assert.assertEquals("4,0,3", frame.toString());
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java
new file mode 100644
index 0000000000..eb128c4b24
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java
@@ -0,0 +1,369 @@
+package com.coding.basic.linklist;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+import java.util.Objects;
+
+public class LinkedList implements List {
+ private int size;
+
+ private Node head;
+
+ private Node last;
+
+
+
+ private static class Node {
+ T data;
+ Node pre;
+ Node next;
+
+ Node(T data) {
+ this.data = data;
+ }
+
+
+ }
+
+ public LinkedList(){
+ this.head = new Node<>(null);
+ }
+
+ @Override
+ public int size() {
+ return this.size;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.size == 0;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ Node node = this.head;
+ while (node.next != null){
+ if (Objects.equals(node.data, o)){
+
+ return true;
+ }
+ node = node.next;
+ }
+ return false;
+ }
+
+ @Override
+ public Object[] toArray() {
+ Object[] dataArray = new Object[size];
+ Node node = head.next;
+ for (int i = 0; i < size&& node != null; i++, node = node.next) {
+ dataArray[i] = node.data;
+
+ }
+ return dataArray;
+ }
+
+ @Override
+ public boolean add(T o) {
+ if (this.last == null){
+ this.last = new Node<>(o);
+ this.last.pre = this.head;
+ this.head.next = this.last;
+ }else {
+ Node oldLast = this.last;
+ this.last = new Node<>(o);
+ this.last.pre = oldLast;
+ oldLast.next = this.last;
+
+ }
+ this.size++;
+ return true;
+ }
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean remove(T o) {
+
+
+ Node curNode = head.next;
+ Node preNode;
+ while (curNode != null){
+ preNode = curNode.pre; //指向前一个节点
+
+ if (Objects.equals(curNode.data, o)){
+ removeNode(preNode, curNode);
+ return true;
+ }
+ curNode = curNode.next;
+ }
+
+ return false;
+ }
+
+ private void removeNode(Node preNode, Node node) {
+
+ if (this.last == node){ //如果删除的是last节点的情况
+ if (preNode == this.head){ //如果只有一个节点的情况
+ this.last = null;
+ }else {
+ this.last = preNode;
+ }
+ }else {
+ node.next.pre = node.pre;
+
+ }
+ preNode.next = node.next;
+
+
+
+
+ this.size--;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void clear() {
+ for (Node x = head; x != null;){
+ Node next = x.next;
+ x.data = null;
+ x.pre = null;
+ x.next = null;
+ x = next;
+ }
+ head = last = null;
+ size = 0;
+
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T get(int index) {
+ return (T) getNode(index).data;
+ }
+
+
+
+ @Override
+ public T set(int index, T o) {
+ Node node = getNode(index);
+ node.data = o;
+ return o;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void add(int index, T o) {
+ ensureIndex(index);
+ Node newNode = new Node<>(o);
+ Node curNode = getNode(index);
+ Node pre = curNode.pre;
+
+ newNode.next = curNode;
+ newNode.pre = pre;
+ curNode.pre = newNode;
+ pre.next = newNode;
+
+ size++;
+
+ }
+
+ @Override
+ public T remove(int index) {
+ Node node = getNode(index);
+ Node pre = node.pre;
+ if (node == last){ //如果是最后一个节点
+ if (pre != head){ //如果是唯一节点
+ last = null;
+ }else {
+ last = node.pre;
+ }
+ }
+
+ pre.next = node.next;
+ if (node.next != null){
+ node.next.pre = pre;
+ }
+ size--;
+ return (T) node.data;
+ }
+
+ @Override
+ public int indexOf(T o) {
+ Node node = head;
+ int index = 0;
+
+ while (node.next != null){
+ node = node.next;
+ if (Objects.equals(node.data, o)){
+ return index;
+ }
+ index ++;
+ }
+ return index;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new LinkedListIterator();
+ }
+
+ @Override
+ public void printf() {
+ Node node = head.next;
+ while (node != null){
+ if (node.next != null) {
+ System.out.print(node.data + " -> ");
+ }else {
+ System.out.print(node.data);
+ }
+ node = node.next;
+ }
+ System.out.println();
+ System.out.println("head = " + head);
+ System.out.println("last = " + last);
+
+ }
+
+
+ private Node getNode(int index) {
+ ensureIndex(index);
+ Node node = this.head;
+ for (int i = 0; i <= index; i++) {
+ node = node.next;
+ }
+ return node;
+ }
+
+ private void ensureIndex(int index) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+ if (head.next == null && head.next.next == null){ //如果链表为空或者只有一个元素,不做变换
+ return;
+ }
+
+ last = head.next;
+
+ Node pre = head.next;
+ Node cur = pre.next;
+ Node next;
+ pre.next = null;
+ while (cur != null){
+ next = cur.next;
+ cur.next = pre;
+ pre = cur;
+ cur = next;
+ }
+ head.next = pre;
+ }
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+ if (isEmpty()){
+ return;
+ }
+ int halfIndex = size / 2;
+
+ if (halfIndex >= 0){
+ head.next = getNode(halfIndex);
+ }
+
+ size = size - halfIndex;
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length){
+ ensureIndex(i);
+ ensureIndex(i + length - 1);
+
+ for (int j = i; j < i + length; j++) {
+ remove(i);
+ }
+ }
+ /**
+ * 假定当前链表和listB均包含已升序排列的整数
+ * 从当前链表中取出那些listB所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){
+ return null;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在listB中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection( LinkedList list){
+ return null;
+ }
+
+ private class LinkedListIterator implements Iterator {
+ private Node node;
+
+ LinkedListIterator(){
+ node = head;
+ }
+ @Override
+ public boolean hasNext() {
+ return node.next != null;
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()){
+ node = node.next;
+ return (T) node.data;
+ }
+ return null;
+ }
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java
new file mode 100644
index 0000000000..db2047f096
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java
@@ -0,0 +1,97 @@
+package com.coding.basic.queue;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ArrayQueue implements Queue {
+
+ private int size;
+ private Object[] dataArray;
+ private int front;
+ private int rear;
+
+ public ArrayQueue(int Capacity) {
+ this.dataArray = new Object[Capacity];
+ this.front = 0;
+ this.rear = 0;
+ this.size = 0;
+ }
+
+ @Override
+ public boolean add(T t) {
+ if (offer(t)){
+ return true;
+ }else {
+ throw new IllegalStateException();
+ }
+ }
+
+ @Override
+ public boolean offer(T t) {
+ if (size >= dataArray.length){
+ return false;
+ }
+
+ dataArray[rear++] = t;
+
+ if (rear == dataArray.length){
+ rear = 0;
+ }
+
+ size++;
+ return true;
+ }
+
+ @Override
+ public T remove() {
+ T value = poll();
+ if (value != null){
+ return value;
+ }else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public T poll() {
+ if (size == 0){
+ return null;
+ }
+
+
+ T value = (T) dataArray[front++];
+ if (front == dataArray.length){
+ front = 0;
+ }
+
+ size--;
+ return value;
+
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+
+ @Override
+ public T peek() {
+ if (size == 0){
+ return null;
+ }else {
+ return (T) dataArray[front];
+ }
+ }
+
+ public void printf() {
+ for (int i = 0; i < size; i++) {
+
+ System.out.print(dataArray[(front + i) % dataArray.length] + " ");
+ }
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java
new file mode 100644
index 0000000000..64f86616f4
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java
@@ -0,0 +1,16 @@
+package com.coding.basic.queue;
+
+public interface Queue {
+
+ boolean add(T t);
+
+ boolean offer(T t);
+
+ T remove();
+
+ T poll();
+
+ boolean isEmpty();
+
+ T peek();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java
new file mode 100644
index 0000000000..9fc2c860d2
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java
@@ -0,0 +1,21 @@
+package com.coding.download;
+
+
+import com.coding.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+ Connection conn;
+ int startPos;
+ int endPos;
+
+ public DownloadThread( Connection conn, int startPos, int endPos){
+
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+ public void run(){
+
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java
new file mode 100644
index 0000000000..ec975a9aae
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java
@@ -0,0 +1,73 @@
+package com.coding.download;
+
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+
+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 = null;
+ try {
+
+ conn = cm.open(this.url);
+
+ int length = conn.getContentLength();
+
+ new DownloadThread(conn,0,length-1).start();
+
+ } catch (ConnectionException e) {
+ e.printStackTrace();
+ }finally{
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+
+
+
+ }
+
+ 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/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..84fbc8afa2
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coding.download;
+
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+import com.coding.download.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(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ 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/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java
new file mode 100644
index 0000000000..65f3dae9c5
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coding.download.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/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1db8b093ec
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coding.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..1d1a83caf2
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coding.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java
new file mode 100644
index 0000000000..c41045b0e8
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coding.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..0ddbf36e1b
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java
@@ -0,0 +1,28 @@
+package com.coding.download.impl;
+
+import com.coding.download.api.Connection;
+
+import java.io.IOException;
+
+
+public class ConnectionImpl implements Connection {
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+
+ return null;
+ }
+
+ @Override
+ public int getContentLength() {
+
+ return 0;
+ }
+
+ @Override
+ public void close() {
+
+
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..0f1c658a60
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,16 @@
+package com.coding.download.impl;
+
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+
+ return null;
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java
new file mode 100644
index 0000000000..26799a83a4
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java
@@ -0,0 +1,124 @@
+package com.coding.litestruts;
+
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class Configuration {
+ Map actions = new HashMap<>();
+
+
+
+ public Configuration(String path) throws IOException {
+
+ URL pathName = Configuration.class.getClassLoader().getResource(path);
+
+ assert pathName != null;
+// InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); 默认则是从ClassPath根下获取,path不能以’/'开头
+// InputStream is = this.getClass().getResourceAsStream("/" + path); // path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取
+// InputStream is = pathName.openStream();
+ InputStream is = new FileInputStream(pathName.getPath());
+
+ parseXML(is);
+
+ try {
+ is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void parseXML(InputStream is) {
+
+ SAXReader reader = new SAXReader();
+
+ try {
+
+ Document doc = reader.read(is);
+ Element root = doc.getRootElement();
+ Iterator it = root.elementIterator("action");
+
+ while (it.hasNext()){
+
+ Element ActionElement = (Element) it.next();
+
+ String actionName = ActionElement.attributeValue("name");
+ String className = ActionElement.attributeValue("class");
+
+ ActionConfig ac = new ActionConfig(actionName, className);
+
+ Iterator it2 = ActionElement.elementIterator();
+
+ while (it2.hasNext()){
+
+ Element resultElement = (Element) it2.next();
+
+ String resultName = resultElement.attributeValue("name");
+ String viewName = resultElement.getTextTrim();
+
+ ac.addViewResult(resultName, viewName);
+ }
+
+ this.actions.put(actionName, ac);
+ }
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getClassName(String actionName) {
+ ActionConfig ac = actions.get(actionName);
+ if (ac == null) {
+ return null;
+ }
+ return ac.getClassName();
+ }
+
+ public String getResultView(String actionName, String resultName) {
+ ActionConfig ac = actions.get(actionName);
+ if (ac == null) {
+ return null;
+ }
+ return ac.getViewName(resultName);
+
+ }
+
+
+ private static class ActionConfig{
+ String name;
+ String clzName;
+ Map viewResult = new HashMap<>();
+
+ public ActionConfig(String name, String clzName) {
+ this.name = name;
+ this.clzName = clzName;
+ }
+
+ public String getClassName() {
+ return clzName;
+ }
+
+ public void addViewResult(String name, String viewName){
+ viewResult.put(name, viewName);
+
+ }
+
+ public String getViewName(String resultName){
+ return viewResult.get(resultName);
+ }
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java
new file mode 100644
index 0000000000..39354518df
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coding.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java
new file mode 100644
index 0000000000..6b761355b1
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java
@@ -0,0 +1,85 @@
+package com.coding.litestruts;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ReflectionUtil {
+
+ public static List getSetterMethods(Class clz) {
+
+ return getMethods(clz, "set");
+ }
+
+ public static void setParameters(Object o, Map params) {
+
+ List methods = getSetterMethods(o.getClass());
+
+ for (String name : params.keySet()) {
+
+ String methodName = "set" + name;
+
+ for (Method method : methods) {
+
+ if (method.getName().equalsIgnoreCase(methodName)){
+ try {
+ method.invoke(o,params.get(name));
+
+
+
+
+
+
+ } catch (IllegalAccessException | InvocationTargetException e) {
+
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ public static List getGetterMethods(Class clz) {
+ return getMethods(clz, "get");
+ }
+
+ private static List getMethods(Class clz, String startWithName) {
+ List methods = new ArrayList<>();
+
+ for (Method method : clz.getDeclaredMethods()) {
+
+ if (method.getName().startsWith(startWithName)) {
+ methods.add(method);
+ }
+ }
+ return methods;
+ }
+
+ public static Map getParamterMap(Object o) {
+ Map params = new HashMap<>();
+
+ List methods = getGetterMethods(o.getClass()); //获得"getXXX"方法
+
+ for (Method method : methods) {
+
+ String methodName = method.getName();
+ String name = methodName.replaceFirst("get", "").toLowerCase(); //获得属性名
+
+ try {
+ params.put(name,method.invoke(o)); //将属性名 和属性值添加进去
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return params;
+
+ }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java
new file mode 100644
index 0000000000..f446bec31c
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java
@@ -0,0 +1,67 @@
+package com.coding.litestruts;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+
+
+ public static View runAction(String actionName, Map parameters) throws NoSuchMethodException, IOException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
+
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+ try {
+ Configuration cfg = new Configuration("struts.xml");
+
+ String clzName = cfg.getClassName(actionName);
+ if (clzName == null) {
+ return null;
+ }
+ String classPath = Struts.class.getClassLoader().getResource("").getPath();
+
+ System.out.println("clzName = " + clzName);
+ System.out.println("classPath = " + classPath);
+ Class> clz = Class.forName(clzName);
+
+ Object o = clz.newInstance();
+ ReflectionUtil.setParameters(o, parameters); //将参数注入属性
+ Method m = clz.getDeclaredMethod("execute");
+ String resultName = (String) m.invoke(o); //执行execute方法
+
+ Map params = ReflectionUtil.getParamterMap(o); //根据action获取model参数
+
+ String jsp = cfg.getResultView(actionName, resultName); //通过返回结果去拿视图名
+
+ View view = new View();
+ view.setJsp(jsp);
+ view.setParameters(params);
+ return view;
+ } catch (IOException | InstantiationException | NoSuchMethodException | InvocationTargetException | ClassNotFoundException | IllegalAccessException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..041fa4d889
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java
@@ -0,0 +1,47 @@
+package com.coding.litestruts;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java
new file mode 100644
index 0000000000..b6e795aa4a
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coding.litestruts;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java
new file mode 100644
index 0000000000..abd49e98e3
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java
@@ -0,0 +1,122 @@
+package com.coding.basic.array;
+
+import com.coding.basic.Iterator;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ArrayListTest {
+
+ private ArrayList arrayList;
+ @Before
+ public void init() {
+ arrayList = new ArrayList<>();
+ for (int i = 0; i < 5; i++) {
+ arrayList.add(i);
+ }
+ }
+
+ @Test
+ public void size() throws Exception {
+ Assert.assertEquals(5, arrayList.size());
+ arrayList.add(6);
+ Assert.assertEquals(6, arrayList.size());
+
+ }
+
+ @Test
+ public void isEmpty() throws Exception {
+ arrayList.clear();
+ Assert.assertEquals(0, arrayList.size());
+ Assert.assertTrue(arrayList.isEmpty());
+ }
+
+ @Test
+ public void contains() throws Exception {
+ Assert.assertTrue(arrayList.contains(0));
+ Assert.assertTrue(arrayList.contains(4));
+ Assert.assertFalse(arrayList.contains(5));
+ }
+
+ @Test
+ public void toArray() throws Exception {
+ Integer[] integers = new Integer[]{0, 1, 2, 3, 4};
+ Assert.assertArrayEquals(integers, arrayList.toArray());
+ }
+
+ @Test
+ public void add() throws Exception {
+ arrayList.add(5);
+ Assert.assertEquals(5, arrayList.get(arrayList.size() - 1).intValue());
+ arrayList.add(0, 6);
+ arrayList.add(3, 7);
+ arrayList.add(arrayList.size(), 8);
+
+ Assert.assertEquals(9, arrayList.size());
+ Assert.assertEquals(6, arrayList.get(0).intValue());
+ Assert.assertEquals(8, arrayList.get(arrayList.size()-1).intValue());
+ Assert.assertEquals(7, arrayList.get(3).intValue());
+ }
+
+ @Test
+ public void remove() throws Exception {
+ arrayList.remove(0);
+ arrayList.remove(3);
+ arrayList.add(5);
+ Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{1,2,3,5});
+
+ arrayList.remove(new Integer(1));
+ arrayList.remove(new Integer(2));
+ arrayList.remove(new Integer(5));
+ arrayList.add(6);
+ arrayList.add(7);
+
+ Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{3,6,7});
+
+ }
+
+
+
+ @Test
+ public void get() throws Exception {
+ Assert.assertEquals(0, arrayList.get(0).intValue());
+ Assert.assertEquals(3, arrayList.get(3).intValue());
+ arrayList.add(5);
+ arrayList.remove(0);
+ Assert.assertEquals(5, arrayList.get(4).intValue());
+ }
+
+ @Test
+ public void set() throws Exception {
+ arrayList.set(0,100);
+ arrayList.set(arrayList.size() - 1, 50);
+ Assert.assertEquals(100, arrayList.get(0).intValue());
+ Assert.assertEquals(50, arrayList.get(arrayList.size() - 1).intValue());
+
+ }
+
+
+
+
+
+ @Test
+ public void indexOf() throws Exception {
+ Assert.assertEquals(0, arrayList.indexOf(0));
+ Assert.assertEquals(1, arrayList.indexOf(1));
+ }
+
+ @Test
+ public void iterator() throws Exception {
+ Iterator iterator = arrayList.iterator();
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(0, iterator.next());
+ Assert.assertEquals(1, iterator.next());
+ }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java
new file mode 100644
index 0000000000..f16a7ab5ab
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java
@@ -0,0 +1,94 @@
+package com.coding.basic.array;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Created by bobi on 2017/4/4.
+ * at code2017
+ */
+public class ArrayUtilTest {
+
+ private static int[] arr;
+
+ @Before
+ public void setUp() throws Exception {
+
+ arr = new int[10];
+
+ for (int i = 0; i < arr.length; i++) {
+ arr[i] = i;
+ }
+
+ }
+
+ private static void arrPrint(int[] arr){
+ for (int i : arr) {
+ System.out.print(i + " ");
+ }
+ System.out.println();
+ }
+
+ @Test
+ public void reverseArray() throws Exception {
+ ArrayUtil.reverseArray(arr);
+ for (int i = 0; i < arr.length; i++) {
+ Assert.assertEquals(9-i, arr[i]);
+ }
+ }
+
+ @Test
+ public void removeZero() throws Exception {
+ int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
+ oldArr = ArrayUtil.removeZero(oldArr);
+
+ Assert.assertArrayEquals(new int[]{1,3,4,5,6,6,5,4,7,6,7,5}, oldArr);
+
+ }
+
+ @Test
+ public void merge() throws Exception {
+ int[] a1 = {3, 5, 7,8};
+ int[] a2 = {4, 5, 6,7} ;
+
+ int[] a3 = ArrayUtil.merge(a1, a2);
+ Assert.assertArrayEquals(new int[]{3,4,5,6,7,8}, a3);
+ }
+
+ @Test
+ public void grow() throws Exception {
+ int[] a1 = {3, 5, 7,8};
+ a1 = ArrayUtil.grow(a1, 3);
+
+ Assert.assertArrayEquals(new int[]{3,5,7,8,0,0,0}, a1);
+ }
+
+ @Test
+ public void fibonacci() throws Exception {
+ int[] arr = ArrayUtil.fibonacci1(100);
+ arrPrint(arr);
+ }
+
+ @Test
+ public void getPrimes() throws Exception {
+ int[] a1 = ArrayUtil.getPrimes(100);
+ arrPrint(a1);
+ }
+
+ @Test
+ public void getPerfectNumbers() throws Exception {
+ int[] a1 = ArrayUtil.getPerfectNumbers(10000);
+ arrPrint(a1);
+ }
+
+ @Test
+ public void join() throws Exception {
+ int[] a1 = {3,4,5,6,7};
+ String str = ArrayUtil.join(a1, "-");
+ System.out.println("str = " + str);
+
+ }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java
new file mode 100644
index 0000000000..f020e64828
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java
@@ -0,0 +1,155 @@
+package com.coding.basic.linklist;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Created by bobi on 2017/3/31.
+ * at code2017
+ */
+public class LinkedListTest {
+
+
+ @Before
+ public void init() {
+ linkedList = new LinkedList<>();
+ for (int i = 0; i < 6; i++) {
+ linkedList.add(1< linkedList;
+
+ @Test
+ public void remove() throws Exception {
+ //测试添加删除
+ {
+ linkedList.printf();
+ linkedList.remove(new Integer(1));
+ linkedList.remove(new Integer(8));
+ linkedList.remove(new Integer(32));
+ linkedList.add(50);
+ linkedList.add(0, 100);
+ Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100, 2, 4, 16, 50});
+
+//
+ linkedList.remove(new Integer(16));
+ linkedList.add(linkedList.size() - 1, 25);
+ Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100,2, 4, 25, 50});
+ }
+
+ }
+
+
+ @Test
+ public void removeFirstHalf() throws Exception {
+ linkedList.removeFirstHalf();
+ linkedList.removeFirstHalf();
+ linkedList.printf();
+ }
+
+ @Test
+ public void getElements() throws Exception {
+
+ }
+
+ @Test
+ public void subtract() throws Exception {
+
+ }
+
+ @Test
+ public void removeDuplicateValues() throws Exception {
+ linkedList.removeFirstHalf();
+ LinkedList list = new LinkedList();
+ list.add(8);
+ list.add(16);
+ list.add(32);
+ Assert.assertArrayEquals(linkedList.toArray(), list.toArray());
+ linkedList.removeFirstHalf();
+ list.remove(0);
+ Assert.assertArrayEquals(linkedList.toArray(), list.toArray());
+
+ }
+
+ @Test
+ public void removeByLength() throws Exception {
+ // 测试删除开始节点
+ {
+ linkedList.remove(0, 2);
+ Assert.assertEquals(linkedList.size(), 4);
+ for (int i = 0; i < 3; i++) {
+ Assert.assertEquals(linkedList.get(i).intValue(), 1<<(i+2));
+ }
+ }
+
+ // 测试删除中间节点
+ {
+ init();
+ linkedList.remove(1, 2);
+ Assert.assertEquals(linkedList.size(), 4);
+ Assert.assertEquals(linkedList.get(0).intValue(), 1);
+ Assert.assertEquals(linkedList.get(1).intValue(), 8);
+ Assert.assertEquals(linkedList.get(2).intValue(), 16);
+ }
+//
+ // 测试删除末尾节点
+ {
+ init();
+ linkedList.remove(4, 2);
+ Assert.assertEquals(linkedList.size(), 4);
+ Assert.assertEquals(linkedList.get(0).intValue(), 1);
+ Assert.assertEquals(linkedList.get(1).intValue(), 2);
+ Assert.assertEquals(linkedList.get(2).intValue(), 4);
+ Assert.assertEquals(linkedList.get(3).intValue(), 8);
+ }
+//
+ // 测试删除全部
+ {
+ init();
+ linkedList.remove(0, 6);
+ Assert.assertEquals(linkedList.size(), 0);
+ }
+ }
+
+ @Test
+ public void intersection() throws Exception {
+
+ }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java
new file mode 100644
index 0000000000..cd0d8abcc8
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java
@@ -0,0 +1,68 @@
+package com.coding.basic.queue;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ArrayQueueTest {
+ private ArrayQueue arrayQueue;
+
+ @Before
+ public void init(){
+ arrayQueue = new ArrayQueue<>(6);
+ for (int i = 0; i < 5; i++) {
+ arrayQueue.add(i);
+ }
+
+ }
+ @Test
+ public void add() throws Exception {
+ Assert.assertTrue(arrayQueue.add(5));
+
+
+ Assert.assertEquals(0, arrayQueue.peek().intValue());
+ Assert.assertEquals(0, arrayQueue.poll().intValue());
+ Assert.assertEquals(1, arrayQueue.poll().intValue());
+
+ for (int i = 0; i < 4; i++) {
+ arrayQueue.remove();
+ }
+ Assert.assertTrue(arrayQueue.isEmpty());
+ }
+
+ @Test
+ public void offer() throws Exception {
+ Assert.assertTrue(arrayQueue.offer(5));
+ Assert.assertFalse(arrayQueue.offer(6));
+ }
+
+ @Test
+ public void remove() throws Exception {
+ arrayQueue.remove();
+ arrayQueue.remove();
+ arrayQueue.remove();
+ arrayQueue.remove();
+
+ arrayQueue.add(5);
+ arrayQueue.add(6);
+ arrayQueue.add(7);
+ arrayQueue.add(8);
+ arrayQueue.add(9);
+
+
+ Assert.assertEquals(4, arrayQueue.remove().intValue());
+ Assert.assertEquals(5, arrayQueue.remove().intValue());
+ Assert.assertEquals(6, arrayQueue.remove().intValue());
+ Assert.assertEquals(7, arrayQueue.remove().intValue());
+ Assert.assertEquals(8, arrayQueue.remove().intValue());
+ Assert.assertEquals(9, arrayQueue.remove().intValue());
+ }
+
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java
new file mode 100644
index 0000000000..40a3013741
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java
@@ -0,0 +1,45 @@
+package com.coding.litestruts;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ConfigurationTest {
+ private Configuration config;
+ @Before
+ public void setUp() throws Exception {
+ config = new Configuration("struts.xml");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+
+ @Test
+ public void testGetClassName(){
+ String clzName = config.getClassName("login");
+ Assert.assertEquals("com.coding.litestruts.LoginAction", clzName);
+ clzName = config.getClassName("logout");
+ Assert.assertEquals("com.coding.litestruts.LogoutAction", clzName);
+
+ }
+
+ @Test
+ public void testGetResultView(){
+ String jsp = config.getResultView("login", "success");
+ Assert.assertEquals("jsp/homepage.jsp", jsp);
+
+ jsp = config.getResultView("login", "fail");
+ Assert.assertEquals("jsp/showLogin.jsp", jsp);
+ }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java
new file mode 100644
index 0000000000..d66188988b
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java
@@ -0,0 +1,124 @@
+package com.coding.litestruts;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ReflectionUtilTest {
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void testGetSetterMethod() throws ClassNotFoundException {
+ String name = "com.coding.litestruts.LoginAction";
+
+ Class clz = Class.forName(name);
+ List methods = ReflectionUtil.getSetterMethods(clz);
+
+ Assert.assertEquals(2, methods.size());
+
+ List expectedNames = new ArrayList<>();
+ expectedNames.add("setName");
+ expectedNames.add("setPassword");
+
+ List acctualNames = new ArrayList<>();
+ for (Method method : methods) {
+ acctualNames.add(method.getName());
+ }
+
+ Assert.assertTrue(acctualNames.containsAll(expectedNames));
+
+ }
+
+ @Test
+ public void testSetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
+ String name = "com.coding.litestruts.LoginAction";
+
+ Class clz = Class.forName(name);
+ Object o = clz.newInstance();
+
+ Map params = new HashMap<>();
+ params.put("name", "test");
+ params.put("password", "1234");
+
+ ReflectionUtil.setParameters(o, params);
+
+
+ Field f = clz.getDeclaredField("name");
+ f.setAccessible(true);
+ Assert.assertEquals("test", f.get(o));
+
+ }
+
+
+ @Test
+ public void testGetGetterMethod() throws ClassNotFoundException {
+ String name = "com.coding.litestruts.LoginAction";
+
+ Class clz = Class.forName(name);
+ List methods = ReflectionUtil.getGetterMethods(clz);
+
+ Assert.assertEquals(3, methods.size());
+
+ List expectedNames = new ArrayList<>();
+ expectedNames.add("getName");
+ expectedNames.add("getPassword");
+ expectedNames.add("getMessage");
+
+ List acctualNames = new ArrayList<>();
+
+ for (Method method : methods) {
+ acctualNames.add(method.getName());
+ }
+
+ Assert.assertTrue(acctualNames.containsAll(expectedNames));
+
+ }
+
+ @Test
+ public void testGetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
+ String name = "com.coding.litestruts.LoginAction";
+ Class clz = Class.forName(name);
+
+ LoginAction o = (LoginAction) clz.newInstance();
+ o.setName("test");
+ o.setPassword("123456");
+
+ Map params;
+ params = ReflectionUtil.getParamterMap(o);
+
+ Assert.assertEquals(3, params.size());
+ Assert.assertEquals(null, params.get("message"));
+ Assert.assertEquals("test", params.get("name"));
+ Assert.assertEquals("123456", params.get("password"));
+
+
+ }
+
+ @Test
+ public void testDouble(){
+ double d = 6.02e23;
+ long i = (long) d;
+ System.out.println(i);
+ }
+}
\ No newline at end of file
diff --git a/group04/120549547/my.txt b/group04/120549547/my.txt
deleted file mode 100644
index 3da1ec26e9..0000000000
--- a/group04/120549547/my.txt
+++ /dev/null
@@ -1 +0,0 @@
-HelloWorld
diff --git a/group04/1299310140/src/com/coderising/download/DownloadThread.java b/group04/1299310140/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..ba5dab2a78
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,38 @@
+package com.coderising.download;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+ Connection conn;
+ int startPos;
+ int endPos;
+ byte[] result;
+
+ public DownloadThread( Connection conn, int startPos, int endPos, byte[] result){
+
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ this.result = result;
+
+ }
+ public void run(){
+ try {
+ byte[] download = this.conn.read(this.startPos, this.endPos);
+ //synchronized(this.result){
+ System.arraycopy(download, 0, this.result, this.startPos, download.length);
+ System.out.println(this.startPos+" "+this.endPos);
+ //}
+ FileOutputStream fos = new FileOutputStream("C:\\b.jpg");
+ fos.write(this.result);
+ fos.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/group04/1299310140/src/com/coderising/download/FileDownloader.java b/group04/1299310140/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..23520a9bd3
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,83 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloader {
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm = new ConnectionManagerImpl();
+
+ 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 connOne = null;
+ Connection connTwo = null;
+ Connection connThree = null;
+ try {
+
+ connOne = cm.open(this.url);
+ connTwo = cm.open(this.url);
+ connThree = cm.open(this.url);
+
+ int length = connOne.getContentLength();
+
+ byte[] result = new byte[length];
+ new DownloadThread(connOne,0,length/3,result).start();
+ new DownloadThread(connTwo,length/3+1,length/2,result).start();
+ new DownloadThread(connThree,length/2+1,length-1,result).start();
+
+ } catch (ConnectionException e) {
+ e.printStackTrace();
+ }finally{
+ if(connOne != null){
+ connOne.close();
+ }
+ if(connTwo != null){
+ connTwo.close();
+ }
+ if(connThree != null){
+ connThree.close();
+ }
+ }
+
+ }
+
+ public void setListener(DownloadListener listener) {
+ this.listener = listener;
+ }
+
+ public void setConnectionManager(ConnectionManager ucm){
+ this.cm = ucm;
+ }
+
+ public DownloadListener getListener(){
+ return this.listener;
+ }
+
+ public static void main(String[] args){
+ new FileDownloader("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg").execute();
+ }
+
+}
diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..3628dd486f
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,59 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+ private URLConnection urlconn;
+ private InputStream fis;
+
+ public ConnectionImpl(URLConnection urlconn) {
+ super();
+ this.urlconn = urlconn;
+ }
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException{
+ this.fis = this.urlconn.getURL().openStream();
+ byte[] buffer = new byte[512];
+ int count = 0;//某次read的字节数
+ int sum = 0;//read的总字节数
+ int length = endPos - startPos + 1;//当前线程需读取的字节数
+ byte[] download = new byte[length];
+ fis.skip(startPos);
+ while((count = fis.read(buffer)) != -1){
+ if(sum + count >= length){
+ System.arraycopy(buffer, 0, download, sum, length - sum);
+ sum = length;
+ break;
+ }else{
+ System.arraycopy(buffer, 0, download, sum, count);
+ sum = sum + count;
+ }
+ }
+ return download;
+ }
+
+ @Override
+ public int getContentLength() {
+ return this.urlconn.getContentLength();
+ }
+
+ @Override
+ public void close() {
+ if(this.fis != null){
+ try {
+ this.fis.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..3035ce9459
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,31 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+ try {
+ URL myurl = new URL("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg");
+ URLConnection urlconn = myurl.openConnection();
+ ConnectionImpl conn = new ConnectionImpl(urlconn);
+ return conn;
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+}
diff --git a/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..3b0b086ee4
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,56 @@
+package com.coderising.jvm.loader;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+
+ private List clzPaths = new ArrayList();
+
+ public byte[] readBinaryCode(String className) throws Exception{
+ //com.coderising.jvm.test.EmployeeV1
+ //"com\\coderising\\jvm\\test\\EmployeeV1"
+ String clzFileName = this.getClassPath() + "\\" + className.replace(".", "\\") + ".class";
+ //FileInputStream BufferedInputStream ByteArrayOutputStream
+ File file = new File(clzFileName);
+
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[1024];
+
+ int length = -1;
+
+ while((length = bis.read(buffer)) != -1){
+ bos.write(buffer,0,length);
+ }
+
+ byte[] result = bos.toByteArray();
+ bis.close();
+ bos.close();
+
+ return result;
+ }
+
+ public void addClassPath(String path) {
+ clzPaths.add(path);
+ }
+
+ public String getClassPath(){
+ String result = "";
+ for(int i = 0;i < clzPaths.size();i++){
+ result = result + clzPaths.get(i);
+ if(i == clzPaths.size() - 1){
+ break;
+ }
+ result = result + ";";
+ }
+ return result;
+ }
+
+}
diff --git a/group04/1299310140/src/com/coding/basic/LinkedList.java b/group04/1299310140/src/com/coding/basic/LinkedList.java
index 4636bbd279..3e908613db 100644
--- a/group04/1299310140/src/com/coding/basic/LinkedList.java
+++ b/group04/1299310140/src/com/coding/basic/LinkedList.java
@@ -208,4 +208,285 @@ public String toString(){
return result;
}
}
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+ if(this.size <= 1){
+ return;
+ }
+ Node before = null;
+ Node pres = this.head;
+ Node after = pres.next;
+ while(after != null){
+ pres.next = before;
+ before = pres;
+ pres = after;
+ after = after.next;
+ }
+ //此时pres指向最后一个节点
+ pres.next = before;
+ this.head = pres;
+ }
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+ */
+ public void removeFirstHalf(){
+ if(this.size <= 1){
+ return;
+ }
+ Node pres = this.head;
+ Node temp = pres;
+ for(int i = 0;i < this.size / 2;i++){
+ temp = pres;
+ pres = pres.next;
+ temp.data = null;
+ temp.next = null;
+ }
+ this.head = pres;
+ this.size = this.size - this.size / 2;
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ * @param index
+ * @param length
+ */
+ public void remove(int index, int length){//若length太大,size不够,则取到末尾
+ if(index < 0 || index >= this.size || length <= 0){//index小于0or大于等于size,length小于等于0,参数错误
+ return;
+ }
+ if(this.size <= 0){
+ return;
+ }
+ if(index == 0){
+ //此时index=0&&length>0&&size>0
+ Node temp = this.head;
+ for(int i = 0;i < length;i++){
+ temp = temp.next;
+ if(temp == null){
+ break;
+ }
+ }
+ this.head = temp;
+ if(temp == null){
+ this.size = 0;
+ }else{
+ this.size = this.size - length;
+ }
+ }else{
+ //此时00&&size>0
+ Node start = this.head;
+ for(int j = 0;j < index-1;j++){
+ start = start.next;
+ }//start指向index-1
+
+ Node end = start;
+ for(int l = 0;l <= length;l++){
+ end = end.next;
+ if(end == null){
+ break;
+ }
+ }//end指向index+length
+ start.next = end;
+ if(end == null){
+ this.size = index;
+ }else{
+ this.size = this.size - length;
+ }
+ }
+ }
+
+ /**
+ * 假定当前链表和listB均包含已升序排列的整数
+ * 从当前链表中取出那些listB所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){//若listB中的index不在0~this.size-1之中,则返回-1
+ if(this.size <= 0 || list == null || list.size <= 0){
+ return null;
+ }
+
+ int[] result = new int[list.size()];
+ Node presIndex = list.head;
+ int index = (int)presIndex.data;
+ for(int i = 0;i < list.size();i++){
+ if(index < 0 || index >= this.size){
+ result[i] = -1;
+ }else{//index:0~this.size-1
+ result[i] = (int)this.get(index);
+ }
+ presIndex = presIndex.next;
+ if(presIndex != null){
+ index = (int)presIndex.data;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在listB中出现的元素
+ * @param list
+ */
+ public void subtract(LinkedList list){//当前链表以及参数列表均递增有序,可有重复值
+ if(this.size == 0 || list == null || list.size() == 0){
+ return;
+ }
+
+ //头节点的删除比较特殊,先不予考虑
+ Node thisPres = this.head.next;//指向被删除节点
+ Node thisPresBefore = this.head;//指向被删除节点的前一个节点
+ Node listPres = list.head;
+ while(thisPres != null && listPres != null){
+ if((int)thisPres.data > (int)listPres.data){
+ listPres = listPres.next;
+ }else if((int)thisPres.data < (int)listPres.data){
+ thisPresBefore = thisPresBefore.next;
+ thisPres = thisPres.next;
+ }else{//(int)thisPres.data == (int)listPres.data
+ thisPresBefore.next = thisPres.next;
+ thisPres = thisPres.next;
+ this.size--;
+ }
+ }
+
+ //最后考虑头节点的删除情况
+ Node first = this.head;
+ Node listPresTwo = list.head;
+ while((int)first.data > (int)listPresTwo.data){
+ listPresTwo = listPresTwo.next;
+ }
+ if((int)first.data == (int)listPresTwo.data){//删除头节点
+ this.head = this.head.next;
+ this.size--;
+ }
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+ if(this.size <= 1){
+ return;
+ }
+
+ Node start = this.head;
+ Node end = start.next;
+ while(end != null){
+ if((int)start.data != (int)end.data){
+ start = end;
+ end = end.next;
+ }else{//start.data == end.data
+ while((int)start.data == (int)end.data){
+ end = end.next;
+ if(end == null){
+ break;
+ }
+ }
+ start.next = end;
+ }
+ }
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+ if(this.size == 0 || max - min < 2 || (int)this.head.data >= max){
+ return;
+ }
+
+ //this.size >= 1 && max - min >= 2 && this.head.data < max
+ int thisHeadData = (int)this.head.data;
+ if(thisHeadData > min && thisHeadData < max){
+ //this.size >= 1 && max - min >= 2 &&
+ //min < this.head.data < max
+ //找到新的头节点即可,this.size减小
+ Node notSmallToMax = this.head.next;
+ int sizeDec = 1;
+ while(notSmallToMax != null){
+ if((int)notSmallToMax.data >= max){
+ break;
+ }
+ notSmallToMax = notSmallToMax.next;
+ sizeDec++;
+ }
+ this.head = notSmallToMax;
+ this.size = this.size - sizeDec;
+ }else{
+ //this.size >= 1 && max - min >= 2 &&
+ //this.head.data <= min
+ Node startBefore = this.head;//第一个>min节点的前一个节点
+ Node start = startBefore.next;//第一个>min的节点
+ while(start != null){
+ if((int)start.data > min){
+ break;
+ }
+ startBefore = start;
+ start = start.next;
+ }
+ if(start == null || (int)start.data >= max){
+ //链表中不存在满足删除条件的元素
+ return;
+ }
+
+ //至少有一个元素需要被删除
+ int sizeDec = 1;
+ Node end = start;//最后一个= max){
+ break;
+ }
+ end = endAfter;
+ endAfter = endAfter.next;
+ sizeDec++;
+ }
+ startBefore.next = endAfter;
+ this.size = this.size - sizeDec;
+ }
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection(LinkedList list){
+ if(list == null || list.size() == 0){
+ return new LinkedList();
+ }
+ if(this.size == 0){
+ return new LinkedList();
+ }
+ LinkedList result = new LinkedList();
+ Node thisPres = this.head;
+ Node listPres = list.head;
+ while(thisPres != null && listPres != null){
+ if((int)thisPres.data < (int)listPres.data){
+ thisPres = thisPres.next;
+ }else if((int)thisPres.data > (int)listPres.data){
+ listPres = listPres.next;
+ }else{
+ //(int)thisPres.data == (int)listPres.data
+ result.add(thisPres.data);
+ thisPres = thisPres.next;
+ listPres = listPres.next;
+ }
+ }
+ return result;
+ }
}
diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..025327e934
--- /dev/null
+++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,136 @@
+package com.coding.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+
+ private static class Node {
+
+ Node prev;
+ Node next;
+ int pageNum;
+
+ Node(int pageNum) {
+ this.pageNum = pageNum;
+ }
+
+ }
+
+ private int capacity;
+ private int size = 0;
+ private Node first;// 链表头
+ private Node last;// 链表尾
+
+ public LRUPageFrame(int capacity) {
+ this.capacity = capacity;
+ }
+
+ /**
+ * 获取缓存中对象
+ *
+ * @param key
+ * @return
+ */
+ public void access(int pageNum) {
+ removeElement(pageNum);
+ addFirst(pageNum);
+ if(this.size > this.capacity){
+ removeLast();
+ }
+ }
+
+ //删除链表的尾节点
+ private void removeLast(){
+ if(this.size == 0){
+ return;
+ }
+ if(this.size == 1){
+ this.first = null;
+ this.last = null;
+ this.size--;
+ }
+ Node curr = this.last;
+ this.last = curr.prev;
+ this.last.next = null;
+ curr.prev = null;
+ this.size--;
+ }
+
+ //根据参数删除双向链表中的某个节点
+ private void removeElement(int pageNum){
+ if(this.size == 0){
+ return;
+ }
+ Node curr = this.first;
+ while(curr.pageNum != pageNum){
+ if(curr.next == null){
+ break;
+ }
+ curr = curr.next;
+ }
+ //此时curr指向被删除节点or链表最后一个节点
+ if(curr.pageNum == pageNum){
+ if(this.first == this.last){//size为1,且该节点需要被删除
+ this.first = null;
+ this.last = null;
+ this.size--;
+ return;
+ }
+ if(curr == this.first){//删除头节点
+ this.first = curr.next;
+ this.first.prev = null;
+ curr.next = null;
+ this.size--;
+ return;
+ }
+ if(curr == this.last){//删除尾节点
+ this.last = curr.prev;
+ this.last.next = null;
+ curr.prev = null;
+ this.size--;
+ return;
+ }
+
+ //删除中间节点
+ //此时size至少为3
+ curr.next.prev = curr.prev;
+ curr.prev.next = curr.next;
+ curr.prev = null;
+ curr.next = null;
+ this.size--;
+ }
+ }
+
+ //向双向链表的头部添加节点
+ private void addFirst(int pageNum){
+ Node curr = new Node(pageNum);
+ if(this.size == 0){
+ this.first = curr;
+ this.last = curr;
+ this.size++;
+ }else{
+ curr.next = this.first;
+ this.first.prev = curr;
+ this.first = curr;
+ this.size++;
+ }
+ }
+
+ public String toString(){
+ StringBuilder buffer = new StringBuilder();
+ Node node = first;
+ while(node != null){
+ buffer.append(node.pageNum);
+
+ node = node.next;
+ if(node != null){
+ buffer.append(",");
+ }
+ }
+ return buffer.toString();
+ }
+
+}
diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..52347f721d
--- /dev/null
+++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,73 @@
+package com.coding.basic.linklist;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LRUPageFrameTest {
+
+ @Test
+ public void testAccess() {
+ LRUPageFrame frame = new LRUPageFrame(3);
+ frame.access(7);
+ frame.access(7);
+ frame.access(0);
+ frame.access(7);
+ frame.access(0);
+ frame.access(1);
+ Assert.assertEquals("1,0,7", frame.toString());
+ frame.access(2);
+ Assert.assertEquals("2,1,0", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,2,1", frame.toString());
+ frame.access(3);
+ Assert.assertEquals("3,0,2", frame.toString());
+ frame.access(0);
+ Assert.assertEquals("0,3,2", frame.toString());
+ frame.access(4);
+ Assert.assertEquals("4,0,3", frame.toString());
+
+ LRUPageFrame frameFive = new LRUPageFrame(5);
+ frameFive.access(7);//7
+ frameFive.access(7);//7
+ frameFive.access(0);//0 7
+ frameFive.access(7);//7 0
+ frameFive.access(0);//0 7
+ frameFive.access(1);//1 0 7
+ Assert.assertEquals("1,0,7", frameFive.toString());
+ frameFive.access(2);//2 1 0 7
+ Assert.assertEquals("2,1,0,7", frameFive.toString());
+ frameFive.access(0);//0 2 1 7
+ Assert.assertEquals("0,2,1,7", frameFive.toString());
+ frameFive.access(0);//0 2 1 7
+ Assert.assertEquals("0,2,1,7", frameFive.toString());
+ frameFive.access(3);//3 0 2 1 7
+ Assert.assertEquals("3,0,2,1,7", frameFive.toString());
+ frameFive.access(0);//0 3 2 1 7
+ Assert.assertEquals("0,3,2,1,7", frameFive.toString());
+ frameFive.access(4);//4 0 3 2 1
+ Assert.assertEquals("4,0,3,2,1", frameFive.toString());
+ }
+
+// @Test
+// public void testAddFirst(){
+// LRUPageFrame frame = new LRUPageFrame(3);
+// frame.addFirst(1);
+// frame.addFirst(2);
+// Assert.assertEquals("2,1", frame.toString());
+// frame.addFirst(3);
+// Assert.assertEquals("3,2,1", frame.toString());
+// frame.addFirst(4);
+// Assert.assertEquals("4,3,2,1", frame.toString());
+// frame.removeElement(3);
+// Assert.assertEquals("4,2,1", frame.toString());
+// frame.removeElement(1);
+// Assert.assertEquals("4,2", frame.toString());
+// frame.removeElement(4);
+// Assert.assertEquals("2", frame.toString());
+// frame.removeElement(2);
+// Assert.assertEquals("", frame.toString());
+// }
+
+}
diff --git a/group04/1796244932/learn01/1.png b/group04/1796244932/learn01/1.png
new file mode 100644
index 0000000000..a25be7d057
Binary files /dev/null and b/group04/1796244932/learn01/1.png differ
diff --git a/group04/1796244932/learn01/pom.xml b/group04/1796244932/learn01/pom.xml
index 06c26f00c8..f62b63ec4b 100644
--- a/group04/1796244932/learn01/pom.xml
+++ b/group04/1796244932/learn01/pom.xml
@@ -21,17 +21,29 @@
dom4j
1.6
+
+
+
+
+ org.jdom
+ jdom
+ 2.0.2
+
+
+
junit
junit
- 4.11
- test
+ 4.12
-
- org.junit.jupiter
- junit-jupiter-api
- RELEASE
-
+
+
+
+ io.netty
+ netty
+ 4.0.0.Alpha8
+
+
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java
index 60254997aa..a425f54e81 100644
--- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java
@@ -1,6 +1,13 @@
package com.dudy.learn01.base;
+import java.util.LinkedList;
+
+/**
+ * 单链表:
+ * 因为没有尾节点
+ * 存放时 add 1 2 3 4 实际是 4 3 2 1
+ */
public class MyLinkedList implements MyList {
private int size = 0;
@@ -24,6 +31,7 @@ public void add(int index, Object o) {
}
private Node getCurrentNode(int index) {// 获取当前节点
+ checkRange(index);
Node current = head;
for(int i = 0; i< size-index -1; i++){
current = current.next;
@@ -56,7 +64,7 @@ public Object remove(int index) {
return node.data;
}
- public int size() {
+ public int size() {
return size;
}
@@ -108,6 +116,7 @@ public Object next() {
}
}
+
private static class Node {
Object data;
Node next;
@@ -118,15 +127,107 @@ public Node(Object data) {
}
}
-
- private void displayLink() {// 自己调试使用
- Node current = head;
- while(current != null){
- System.out.print(current.data);
- current = current.next;
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+
+ if(head == null || head.next == null){
+ return ;
+ }
+
+ Node current = head; // 当前节点 我的头节点是有数据的
+
+ while (current.next != null){
+ Node p = current.next; // 当前节点的下一个
+ current.next = p.next; // 当前节点的next -> current.next.next (p.next)
+ p.next = head; // current.next(p) -> head.next (插入到 head 和 第一个数据之间)
+ head = p;
}
- System.out.println("");
}
-
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+
+ int base = size;
+ Node currentNode = getCurrentNode(base / 2);
+ currentNode = null;
+ size = size - base/2;
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length){
+
+ Node preNode = getCurrentNode(size - i -1);
+ Node nextNode = getCurrentNode(size - i - length-1);
+ nextNode.next = preNode;
+ size = size -length;
+ }
+ /**
+ * 假定当前链表和list均包含已升序排列的整数
+ * 从当前链表中取出那些list所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param src
+ */
+ public Object[] getElements(int[] src){
+ Object des[] = new Object[src.length];
+
+ for (int i = 0; i < src.length; i++){
+ des[i] = getCurrentNode(size - 1 - i).data;
+ }
+
+ return des;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在list中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max){
+
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection( LinkedList list){
+ return null;
+ }
}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java
new file mode 100644
index 0000000000..84e9bd5d2c
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java
@@ -0,0 +1,40 @@
+package com.dudy.learn01.designPattern.singleton;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by dudy on 2017/3/6.
+ */
+public enum EnumSingleton {
+
+ SINGLETON;
+ private EnumSingleton(){}
+
+
+ public static void main(String[] args) {
+
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 6000 * 10, TimeUnit.MILLISECONDS,
+ new ArrayBlockingQueue(5));
+
+
+ for (int i = 0; i< 16; i++){
+ executor.execute(new EnumSingletonTest());
+ }
+
+ executor.shutdown();
+
+
+ }
+}
+
+
+class EnumSingletonTest implements Runnable{
+
+ @Override
+ public void run() {
+ EnumSingleton singleton = EnumSingleton.SINGLETON;
+ System.out.println(singleton.hashCode());
+ }
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java
new file mode 100644
index 0000000000..8de831c354
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java
@@ -0,0 +1,66 @@
+package com.dudy.learn01.designPattern.singleton;
+
+import java.io.Serializable;
+import java.util.concurrent.*;
+
+/**
+ * Created by dudy on 2017/3/6.
+ * 双检索 方式
+ * jdk1.5 以后 其实是线程安全的。
+ * 序列化会 破坏 单利
+ *
+ */
+public class SingletonDemo1 implements Serializable{
+
+ private static volatile SingletonDemo1 singleton = null; // 加 volatile 是为了 可见性,另一个就是 避免重排序
+
+ private SingletonDemo1(){}
+
+ public static SingletonDemo1 getIntance(){
+
+ if (singleton == null){// 第一个避免 在 synchronized 中 一直排队
+ synchronized (SingletonDemo1.class){
+
+ if (singleton == null){// 如果对象为空,才被创建
+ singleton = new SingletonDemo1();
+ }
+
+ }
+ }
+
+ return singleton;
+ }
+
+
+ /**
+ * 解决 反序列化的问题
+ * @return
+ */
+ private Object readResolve() {
+ return singleton;
+ }
+
+ public static void main(String[] args) {
+
+ ExecutorService threadPool = Executors.newFixedThreadPool(10);
+
+ for (int i= 0 ;i < 5; i++){
+ threadPool.execute(new TestRunable());
+ }
+
+ threadPool.shutdown();
+
+ //new ThreadPoolExecutor(10,20,1000*2,new BlockingQueue(),)
+
+
+ }
+
+}
+
+ class TestRunable implements Runnable{
+
+ public void run() {
+ SingletonDemo1 intance = SingletonDemo1.getIntance();
+ System.out.println(intance.hashCode());
+ }
+ }
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java
new file mode 100644
index 0000000000..d8b484cd15
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java
@@ -0,0 +1,63 @@
+package com.dudy.learn01.designPattern.singleton;
+
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by dudy on 2017/3/6.
+ *
+ * 静态内部类方式 实现
+ *
+ * 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,
+ * 它跟饿汉式不同的是(很细微的差别):饿汉式是只要Singleton类被装载了,
+ * 那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,
+ * instance不一定被初始化。因为SingletonHolder类没有被主动使用,
+ * 只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,
+ * 从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,
+ * 另外一方面,我不希望在Singleton类加载时就实例化,
+ * 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,
+ * 那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比饿汉式更加合理
+ *
+ */
+public class StaticClassInnerSingleton {
+
+ // 构造器 私有化
+ private StaticClassInnerSingleton(){}
+
+ private static class SingletonHolder{
+ private static final StaticClassInnerSingleton INSTANCE = new StaticClassInnerSingleton();
+ }
+
+
+ public static StaticClassInnerSingleton getInstance(){
+ return SingletonHolder.INSTANCE;
+ }
+
+
+ public static void main(String[] args) {
+
+
+ ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10,
+ 6000 * 10, TimeUnit.MILLISECONDS,
+ new LinkedBlockingDeque());
+
+ for (int i= 0; i<20; i++){
+ pool.execute(new StaicSingletonTest());
+ //System.out.println(StaticClassInnerSingleton.getInstance().hashCode());
+ }
+
+ pool.shutdown();
+ }
+
+
+
+}
+
+class StaicSingletonTest implements Runnable{
+
+ public void run() {
+ StaticClassInnerSingleton intance = StaticClassInnerSingleton.getInstance();
+ System.out.println(intance.hashCode());
+ }
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java
new file mode 100644
index 0000000000..97ca01e13b
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java
@@ -0,0 +1,59 @@
+package com.dudy.learn01.download;
+
+import com.dudy.learn01.download.api.Connection;
+
+import java.io.*;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+
+public class DownloadThread extends Thread{
+
+ private Connection conn;
+ private int startPos;
+ private int endPos;
+ private RandomAccessFile raf;
+ //private CyclicBarrier cb;
+ private CountDownLatch downLatch;
+
+
+ public DownloadThread(Connection conn, int startPos, int endPos,
+ /*CyclicBarrier cb*/
+ CountDownLatch downLatch){
+
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+// this.cb = cb;
+ this.downLatch = downLatch;
+ }
+ public void run(){
+ try {
+ byte[] read = conn.read(startPos, endPos);
+
+ System.out.println("read length: -> "+read.length);
+ //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的
+ raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw");
+ //将写文件的指针指向下载的起始点
+ raf.seek(startPos);
+ raf.write(read, 0, read.length);
+
+ downLatch.countDown();
+// cb.await();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (raf != null){
+ raf.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (conn != null){
+ conn.close();
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java
new file mode 100644
index 0000000000..eee5825b84
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java
@@ -0,0 +1,93 @@
+package com.dudy.learn01.download;
+
+import com.dudy.learn01.download.api.Connection;
+import com.dudy.learn01.download.api.ConnectionManager;
+import com.dudy.learn01.download.api.DownloadListener;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+
+public class FileDownloader {
+
+ private static final int THREAD_NUM = 3;
+
+ private String url;
+
+ private DownloadListener listener;
+
+ private ConnectionManager cm;
+
+
+ public FileDownloader(String _url) {
+ this.url = _url;
+
+ }
+
+ public void execute() throws IOException {
+ // 在这里实现你的代码, 注意: 需要用多线程实现下载
+ // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+ // (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 = null;
+ try {
+ //CyclicBarrier cb = new CyclicBarrier(THREAD_NUM);
+ CountDownLatch downLatch = new CountDownLatch(THREAD_NUM);
+
+ conn = cm.open(this.url);
+
+ int length = conn.getContentLength();
+
+ for (int i = 0;i < THREAD_NUM; i++){
+
+ int start=i*length/THREAD_NUM;
+ int end = (i+1)*length/THREAD_NUM-1;
+ if(i==THREAD_NUM-1)
+ {
+ end =length;
+ }
+
+ new DownloadThread(cm.open(url),start,end,downLatch).start();
+ }
+
+ //cb.await();
+ downLatch.await();
+ getListener().notifyFinished();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }finally{
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+
+
+
+ }
+
+ public void setListener(DownloadListener listener) {
+ this.listener = listener;
+ }
+
+
+
+ public void setConnectionManager(ConnectionManager ucm){
+ this.cm = ucm;
+ }
+
+ public DownloadListener getListener(){
+ return this.listener;
+ }
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java
new file mode 100644
index 0000000000..513c0004e9
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.dudy.learn01.download.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();
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java
new file mode 100644
index 0000000000..71af9bf06d
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.dudy.learn01.download.api;
+
+public class ConnectionException extends Exception {
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..5f4777f6e0
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java
@@ -0,0 +1,13 @@
+package com.dudy.learn01.download.api;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException, IOException;
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java
new file mode 100644
index 0000000000..fa3b5bead0
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.dudy.learn01.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..5eb6b45d41
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java
@@ -0,0 +1,89 @@
+package com.dudy.learn01.download.impl;
+
+import com.dudy.learn01.download.api.Connection;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ConnectionImpl implements Connection {
+
+
+ private HttpURLConnection connection;
+
+ public ConnectionImpl(String url) {
+ try {
+ this.connection = (HttpURLConnection) new URL(url).openConnection();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+
+ connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+
+ InputStream in = connection.getInputStream();
+ byte buffer[] = new byte[endPos-startPos+1];
+ byte result[] = new byte[endPos-startPos+1];
+ int count = 0; // 记录已经读取的数据
+ int length = -1 ;
+
+ while ((length = in.read(buffer)) > 0){
+ System.arraycopy(buffer,0,result,count,length);
+ count += length;
+ }
+ return result;
+ }
+
+ @Override
+ public int getContentLength() {
+ return connection.getContentLength();
+ }
+
+ @Override
+ public void close() {
+ if (connection != null){
+ connection.disconnect();
+ }
+ }
+
+ public static void main(String[] args) throws Exception{
+ //String PATH = "http://demo2.yun.myuclass.com/upload/demo2.yun.myuclass.com/winshare/pagelogo/250617391.png";
+ String PATH = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png";
+
+ URL url = new URL(PATH);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ //conn.setConnectTimeout(5000);
+ //conn.setRequestMethod("GET");
+ //设置头部的参数,表示请求服务器资源的某一部分
+ //conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+ //设置了上面的头信息后,响应码为206代表请求资源成功,而不再是200
+ int code = conn.getResponseCode();
+ System.out.println(conn.getContentLength());
+ if(code == 200){
+
+ InputStream is = conn.getInputStream();
+ int hasRead = 0;
+ byte[] buf = new byte[conn.getContentLength()];
+ System.out.println(buf.length);
+ //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的
+ RandomAccessFile raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw");
+ //将写文件的指针指向下载的起始点
+ raf.seek(0);
+
+ while((hasRead = is.read(buf,0,conn.getContentLength())) > 0) {
+ System.out.println("hasRead = " + hasRead);
+ raf.write(buf, 0, hasRead);
+ }
+ is.close();
+ raf.close();
+ conn.disconnect();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..809f98d91b
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,25 @@
+package com.dudy.learn01.download.impl;
+
+import com.dudy.learn01.download.api.Connection;
+import com.dudy.learn01.download.api.ConnectionException;
+import com.dudy.learn01.download.api.ConnectionManager;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+
+ private Connection connection = null;
+
+ @Override
+ public Connection open(String url) throws ConnectionException, IOException {
+
+ connection = new ConnectionImpl(url);
+
+ return connection;
+ }
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java
new file mode 100644
index 0000000000..e4239ae521
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java
@@ -0,0 +1,64 @@
+package com.dudy.learn01.juc;
+
+/**
+ * Created by dudy on 2017/3/9.
+ *
+ * 4. ThreadLocal 这个类实现原理和用途,在哪里用到了
+ * 每个ThreadLocal可以放一个线程级别的变量,但是它本身可以被多个线程共享变量,而且又可以达到线程安全的目的,且绝对线程安全
+ * spring的事物管理Session, 连接池管理 Connection
+ * https://my.oschina.net/huangyong/blog/159725
+ * 数据库事物的前提是: 必须是同一个连接
+ */
+public class ThreadLocalTest {
+
+ static class Resource{
+ public static final ThreadLocal RESOURCE1 = new ThreadLocal();
+ public static final ThreadLocal RESOURCE2 = new ThreadLocal();
+ }
+
+ static class A {
+ public void setOne(String str){
+ Resource.RESOURCE1.set(str);
+ }
+
+ public void setTwo(String str){
+ Resource.RESOURCE2.set(str);
+ }
+ }
+
+ static class B {
+ public void display(){
+ System.out.println(Resource.RESOURCE1.get()
+ +":" + Resource.RESOURCE2.get());
+ }
+ }
+
+ public static void main(String[] args) {
+
+ final A a = new A();
+ final B b = new B();
+
+ for (int i = 0; i< 5 ;i++){
+
+ final String resource1 = "Thread_" + i;
+ final String resource2 = "value " + i;
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ a.setOne(resource1);
+ a.setTwo(resource2);
+ b.display();
+ }finally {
+ Resource.RESOURCE2.remove();
+ Resource.RESOURCE1.remove();
+ }
+ }
+ }).start();
+ }
+
+ }
+
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java
index bbe8c108ca..c08ae7ae49 100644
--- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java
@@ -46,6 +46,7 @@ public static View runAction(String actionName, Map parameters) {
for (Map.Entry entry : parameters.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
// 这里 只能传递object吧
+ //actionClass.gett
Method method = actionClass.getDeclaredMethod(methodNameconversion(entry.getKey()), String.class);
method.setAccessible(true);
method.invoke(base,entry.getValue());
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java
new file mode 100755
index 0000000000..987696acde
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java
@@ -0,0 +1,113 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+
+public class Configuration {
+
+ Map actions = new HashMap<>();
+
+ public Configuration(String fileName) {
+
+ String packageName = this.getClass().getPackage().getName();
+
+ packageName = packageName.replace('.', '/');
+
+ InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName);
+
+ parseXML(is);
+
+ try {
+ is.close();
+ } catch (IOException e) {
+ throw new ConfigurationException(e);
+ }
+ }
+
+ private void parseXML(InputStream is){
+
+ SAXBuilder builder = new SAXBuilder();
+
+ try {
+
+ Document doc = builder.build(is);
+
+ Element root = doc.getRootElement();
+
+ for(Element actionElement : root.getChildren("action")){
+
+ String actionName = actionElement.getAttributeValue("name");
+ String clzName = actionElement.getAttributeValue("class");
+
+ ActionConfig ac = new ActionConfig(actionName, clzName);
+
+ for(Element resultElement : actionElement.getChildren("result")){
+
+ String resultName = resultElement.getAttributeValue("name");
+ String viewName = resultElement.getText().trim();
+
+ ac.addViewResult(resultName, viewName);
+
+ }
+
+ this.actions.put(actionName, ac);
+ }
+
+
+ } catch (JDOMException e) {
+ throw new ConfigurationException(e);
+
+ } catch (IOException e) {
+ throw new ConfigurationException(e);
+
+ }
+
+
+ }
+
+ public String getClassName(String action) {
+ ActionConfig ac = this.actions.get(action);
+ if(ac == null){
+ return null;
+ }
+ return ac.getClassName();
+ }
+
+ public String getResultView(String action, String resultName) {
+ ActionConfig ac = this.actions.get(action);
+ if(ac == null){
+ return null;
+ }
+ return ac.getViewName(resultName);
+ }
+
+ private static class ActionConfig{
+
+ String name;
+ String clzName;
+ Map viewResult = new HashMap<>();
+
+
+ public ActionConfig(String actionName, String clzName) {
+ this.name = actionName;
+ this.clzName = clzName;
+ }
+ public String getClassName(){
+ return clzName;
+ }
+ public void addViewResult(String name, String viewName){
+ viewResult.put(name, viewName);
+ }
+ public String getViewName(String resultName){
+ return viewResult.get(resultName);
+ }
+ }
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java
new file mode 100755
index 0000000000..a584a7077d
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java
@@ -0,0 +1,21 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.io.IOException;
+
+import org.jdom2.JDOMException;
+
+public class ConfigurationException extends RuntimeException {
+
+ public ConfigurationException(String msg) {
+ super(msg);
+ }
+
+ public ConfigurationException(JDOMException e) {
+ super(e);
+ }
+
+ public ConfigurationException(IOException e) {
+ super(e);
+ }
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java
new file mode 100755
index 0000000000..0f3c74e69a
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java
@@ -0,0 +1,50 @@
+package com.dudy.learn01.litestruts.format;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class ConfigurationTest {
+
+
+ Configuration cfg = new Configuration("struts.xml");
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetClassName() {
+
+ String clzName = cfg.getClassName("login");
+ Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName);
+
+
+ clzName = cfg.getClassName("logout");
+ Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName);
+ }
+
+ @Test
+ public void testGetResultView(){
+ String jsp = cfg.getResultView("login","success");
+ Assert.assertEquals("/jsp/homepage.jsp", jsp);
+
+ jsp = cfg.getResultView("login","fail");
+ Assert.assertEquals("/jsp/showLogin.jsp", jsp);
+
+ jsp = cfg.getResultView("logout","success");
+ Assert.assertEquals("/jsp/welcome.jsp", jsp);
+
+ jsp = cfg.getResultView("logout","error");
+ Assert.assertEquals("/jsp/error.jsp", jsp);
+
+ }
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java
new file mode 100755
index 0000000000..3672d5a990
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java
@@ -0,0 +1,39 @@
+package com.dudy.learn01.litestruts.format;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java
new file mode 100755
index 0000000000..6ab3715730
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java
@@ -0,0 +1,123 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ReflectionUtil {
+
+ public static List getSetterMethods(Class clz) {
+
+ return getMethods(clz,"set");
+
+ }
+
+ public static void setParameters(Object o, Map params) {
+
+ List methods = getSetterMethods(o.getClass());
+
+ for(String name : params.keySet() ){
+
+ String methodName = "set" + name;
+
+ for(Method m: methods){
+
+ if(m.getName().equalsIgnoreCase(methodName)){
+ try {
+ m.invoke(o, params.get(name));
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ }
+
+ public static List getGetterMethods(Class> clz) {
+ return getMethods(clz,"get");
+ }
+
+ private static List getMethods(Class> clz, String startWithName){
+
+ List methods = new ArrayList<>();
+
+ for(Method m : clz.getDeclaredMethods()){
+
+ if(m.getName().startsWith(startWithName)){
+
+ methods.add(m);
+
+ }
+
+ }
+
+ return methods;
+ }
+
+ public static Map getParamterMap(Object o) {
+
+ Map params = new HashMap<>();
+
+ List methods = getGetterMethods(o.getClass());
+
+ for(Method m : methods){
+
+ String methodName = m.getName();
+ String name = methodName.replaceFirst("get", "").toLowerCase();
+ try {
+ Object value = m.invoke(o);
+ params.put(name, value);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+
+ e.printStackTrace();
+ }
+ }
+
+ return params;
+ }
+
+ ////////////////////////Backup ///////////////////////////////////
+
+ public static List getGetterMethods_V1(Class> clz) {
+
+ List methods = new ArrayList<>();
+
+ for(Method m : clz.getDeclaredMethods()){
+
+ if(m.getName().startsWith("get")){
+
+ methods.add(m);
+
+ }
+
+ }
+
+ return methods;
+ }
+
+ public static List getSetterMethods_V1(Class clz) {
+
+ List methods = new ArrayList<>();
+
+ for(Method m : clz.getDeclaredMethods()){
+
+ if(m.getName().startsWith("set")){
+
+ methods.add(m);
+
+ }
+
+ }
+
+ return methods;
+
+ }
+
+
+
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java
new file mode 100755
index 0000000000..174808fe62
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java
@@ -0,0 +1,113 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class ReflectionUtilTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetSetterMethod() throws Exception {
+
+ String name = "com.coderising.litestruts.LoginAction";
+ Class> clz = Class.forName(name);
+ List methods = ReflectionUtil.getSetterMethods(clz);
+
+ Assert.assertEquals(2, methods.size());
+
+ List expectedNames = new ArrayList<>();
+ expectedNames.add("setName");
+ expectedNames.add("setPassword");
+
+ Set acctualNames = new HashSet<>();
+ for(Method m : methods){
+ acctualNames.add(m.getName());
+ }
+
+ Assert.assertTrue(acctualNames.containsAll(expectedNames));
+ }
+
+ @Test
+ public void testSetParameters() throws Exception{
+
+ String name = "com.coderising.litestruts.LoginAction";
+ Class> clz = Class.forName(name);
+ Object o = clz.newInstance();
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+ ReflectionUtil.setParameters(o,params);
+
+
+
+ Field f = clz.getDeclaredField("name");
+ f.setAccessible(true);
+ Assert.assertEquals("test", f.get(o));
+
+ f = clz.getDeclaredField("password");
+ f.setAccessible(true);
+ Assert.assertEquals("1234", f.get(o));
+ }
+ @Test
+ public void testGetGetterMethod() throws Exception{
+ String name = "com.coderising.litestruts.LoginAction";
+ Class> clz = Class.forName(name);
+ List methods = ReflectionUtil.getGetterMethods(clz);
+
+ Assert.assertEquals(3, methods.size());
+
+ List expectedNames = new ArrayList<>();
+ expectedNames.add("getMessage");
+ expectedNames.add("getName");
+ expectedNames.add("getPassword");
+
+ Set acctualNames = new HashSet<>();
+ for(Method m : methods){
+ acctualNames.add(m.getName());
+ }
+
+ Assert.assertTrue(acctualNames.containsAll(expectedNames));
+ }
+
+ @Test
+ public void testGetParamters() throws Exception{
+ String name = "com.coderising.litestruts.LoginAction";
+ Class> clz = Class.forName(name);
+ LoginAction action = (LoginAction)clz.newInstance();
+ action.setName("test");
+ action.setPassword("123456");
+
+
+
+
+ Map params = ReflectionUtil.getParamterMap(action);
+
+ Assert.assertEquals(3, params.size());
+
+ Assert.assertEquals(null, params.get("messaage") );
+ Assert.assertEquals("test", params.get("name") );
+ Assert.assertEquals("123456", params.get("password") );
+ }
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java
new file mode 100755
index 0000000000..661fd96ebe
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java
@@ -0,0 +1,68 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+ private final static Configuration cfg = new Configuration("struts.xml");
+
+ public static View runAction(String actionName, Map parameters) {
+
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+
+
+
+ String clzName = cfg.getClassName(actionName);
+
+ if(clzName == null){
+ return null;
+ }
+
+ try {
+
+ Class> clz = Class.forName(clzName);
+ Object action = clz.newInstance();
+
+ ReflectionUtil.setParameters(action, parameters);
+
+ Method m = clz.getDeclaredMethod("execute");
+ String resultName = (String)m.invoke(action);
+
+ Map params = ReflectionUtil.getParamterMap(action);
+ String resultView = cfg.getResultView(actionName, resultName);
+ View view = new View();
+ view.setParameters(params);
+ view.setJsp(resultView);
+ return view;
+
+
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java
new file mode 100755
index 0000000000..f3b177e54c
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java
new file mode 100755
index 0000000000..93c73bd359
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java
@@ -0,0 +1,23 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml
new file mode 100755
index 0000000000..4c6eeabbd4
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml
@@ -0,0 +1,11 @@
+
+
+
+ /jsp/homepage.jsp
+ /jsp/showLogin.jsp
+
+
+ /jsp/welcome.jsp
+ /jsp/error.jsp
+
+
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java
new file mode 100644
index 0000000000..2763af6d55
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java
@@ -0,0 +1,104 @@
+package com.dudy.learn01.utils;
+
+import java.util.Arrays;
+
+/**
+ * Created by dudy on 2017/3/6.
+ * 练习数组的各种排序
+ * 参考:http://wiki.jikexueyuan.com/project/java-special-topic/sort.html
+ * http://www.cnblogs.com/liuling/p/2013-7-24-01.html
+ *
+ * 内排序有可以分为以下几类:
+
+ (1)、插入排序:直接插入排序、二分法插入排序、希尔排序。
+
+ (2)、选择排序:简单选择排序、堆排序。
+
+ (3)、交换排序:冒泡排序、快速排序。
+
+ (4)、归并排序
+
+ (5)、基数排序
+ *
+ */
+public class ArraySortDemo {
+
+
+ /**
+ * 二分法查找 插入
+ * 和 直接插入排序不同的是: 查找 要插入的位置的方式不同
+ * 二分法前提是有序的**
+ */
+ public static void dichotomySort(int src[]){
+
+ for (int i = 0; i< src.length ; i++){
+ int temp = src[i];
+ int right = i - 1;
+ int mid = 0;
+ int left = 0;
+ while (left <= right){
+ mid = (left + right)/2;
+ if (temp > src[mid]){
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+
+ for (int j = i-1;j>=left ; j--){
+ src[j+1] = src[j];
+ }
+
+ System.out.println("left = " + left +" ,mid = " + mid + " ,right = " + right);
+ src[left] = temp;
+
+ }
+ }
+
+
+
+
+ /**
+ * 直接插入排序
+ * 思想:假定前边是有序地部分, 后边无序的插入到前边部分
+ * 可以转变思想: 从后往前遍历, 将有序部分大于当前的值 往后移
+ * @param src
+ */
+ public static void directInsertSort(int[] src){
+
+ for (int i = 1;i < src.length ; i++){
+ // 待插入的元素
+ int temp = src[i];
+ int j;
+ for ( j = i -1; j >= 0; j--){
+ // 大于 temp的往后移动
+ if (src[j] > temp){
+ src[j+1] = src[j];
+ } else {
+ break;
+ }
+ }// 此时遍历完 j+1 为要插入的位置
+ src[j+1] = temp;
+ }
+
+ }
+
+
+
+ public static void main(String[] args) {
+ int a[] = new int[]{46,89,14,44,90,32,25,67,23};
+ // 14,23,25,32,44,46,67,89,90
+ //Arrays.sort(a);
+
+
+ //directInsertSort(a);
+
+ dichotomySort(a);
+
+ for (int i = 0; i< a.length ; i++){
+ System.out.print(a[i] + ",");
+ }
+
+ }
+
+}
diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java
index c6ebb096ec..cce7a1c163 100644
--- a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java
+++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java
@@ -2,10 +2,69 @@
import java.util.LinkedList;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
public class MyLinkedListTest {
+ MyLinkedList list = new MyLinkedList();
+
+ @Before
+ public void init(){
+ list.add(1);
+ list.add(2);
+ list.add(3);
+ list.add(4);
+ list.add(5);
+ }
+
+ @After
+ public void after(){
+ for(MyIterator it = list.iterator(); it.hasNext();){
+ System.out.print(it.next() + " ");
+ }
+ }
+
+ @Test
+ public void reverse() throws Exception {
+ list.reverse();
+ }
+
+ @Test
+ public void removeFirstHalf() throws Exception {
+ list.removeFirstHalf();
+ }
+
+ @Test
+ public void remove() throws Exception {
+ list.remove(0,2);
+ }
+
+ @Test
+ public void getElements() throws Exception {
+
+ }
+
+ @Test
+ public void subtract() throws Exception {
+
+ }
+
+ @Test
+ public void removeDuplicateValues() throws Exception {
+
+ }
+
+ @Test
+ public void removeRange() throws Exception {
+
+ }
+
+ @Test
+ public void intersection() throws Exception {
+
+ }
@Test
diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..fc427e2171
--- /dev/null
+++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java
@@ -0,0 +1,53 @@
+package com.dudy.learn01.download;
+
+import com.dudy.learn01.download.api.ConnectionManager;
+import com.dudy.learn01.download.api.DownloadListener;
+import com.dudy.learn01.download.impl.ConnectionManagerImpl;
+import org.junit.Test;
+
+
+import java.io.IOException;
+
+
+public class FileDownloaderTest {
+ boolean downloadFinished = false;
+
+
+
+ @Test
+ public void testDownload() throws IOException {
+
+ //String url = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png";
+ String url = "http://img.lanrentuku.com/img/allimg/1606/14665573271238.jpg";
+ FileDownloader downloader = new FileDownloader(url);
+
+ ConnectionManager cm = new ConnectionManagerImpl();
+ downloader.setConnectionManager(cm);
+
+ downloader.setListener(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ downloadFinished = true;
+ }
+ });
+
+
+ downloader.execute();
+
+ // 等待多线程下载程序执行完毕
+ while (!downloadFinished) {
+ try {
+ System.out.println("还没有下载完成,休眠五秒");
+ //休眠5秒
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("下载完成!");
+
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/group04/349184132/Study/bin/com/test/student2.xml b/group04/349184132/Study/bin/com/test/student2.xml
deleted file mode 100644
index e21862ec75..0000000000
--- a/group04/349184132/Study/bin/com/test/student2.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- hello text
- world text
-
diff --git a/group04/349184132/Study/bin/com/test/students.xml b/group04/349184132/Study/bin/com/test/students.xml
deleted file mode 100644
index 0a503c9f6c..0000000000
--- a/group04/349184132/Study/bin/com/test/students.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- hello Text1
- hello Text2
- hello Text3
- world text1
- world text2
- world text3
-
\ No newline at end of file
diff --git a/group04/349184132/Study/src/com/coderising/download/DownloadThread.java b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..2b806a7f44
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,49 @@
+package com.coderising.download;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread {
+ Connection conn;
+ int startPos;
+ int endPos;
+ int threadId = 0;
+ CyclicBarrier barrier;
+
+ public DownloadThread(CyclicBarrier barrier, Connection conn, int threadId,
+ int startPos, int endPos) {
+ this.barrier = barrier;
+ this.conn = conn;
+ this.threadId = threadId;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+
+ public void run() {
+ RandomAccessFile raf = null;
+ try {
+ raf = new RandomAccessFile("yunpan.exe", "rwd");
+
+ raf.seek(startPos);
+
+ byte[] buffer = conn.read(startPos, endPos);
+
+ raf.write(buffer, 0, buffer.length);
+ raf.close();
+ barrier.await();
+ System.out.println("threadId" + threadId +"download success !");
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (BrokenBarrierException e) {
+ e.printStackTrace();
+ }
+
+ }
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/FileDownloader.java b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..281dafde96
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,112 @@
+package com.coderising.download;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+public class FileDownloader {
+
+ boolean isFinished = false;
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+ private static final int THREAD_NUM = 3;
+
+ 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方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+
+ CyclicBarrier barrier = new CyclicBarrier(THREAD_NUM,new Runnable(){
+
+ @Override
+ public void run() {
+ listener.notifyFinished();
+ }
+
+ });
+
+ Connection conn = null;
+ try {
+ conn = cm.open(url);
+
+ int length = conn.getContentLength();
+ System.out.println("----文件总长度---- :" + length);
+ RandomAccessFile raf = new RandomAccessFile("yunpan.exe","rwd");
+
+ raf.setLength(length);
+
+ int block = length / THREAD_NUM;
+
+ for(int threadId = 0; threadId < THREAD_NUM; threadId++){
+ int startPos = (threadId) * block;
+ int endPos = (threadId + 1 ) * block -1;
+ if(threadId-1 == THREAD_NUM){
+ endPos = length;
+ }
+ System.out.println("---threadId--- :" + threadId +
+ "---startIndex---" + startPos +
+ "---endIndex---" + endPos);
+ //开启 线程
+ URL u = new URL(url);
+ new DownloadThread(barrier,cm.open(url),threadId,startPos,endPos).start();
+ }
+
+
+ } catch (ConnectionException e) {
+
+ e.printStackTrace();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally{
+ if(conn!=null){
+ conn.close();
+ }
+ }
+
+ }
+
+ 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/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..604712d2a9
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,58 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+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://down.360safe.com/yunpan/360wangpan_setup.exe";
+ FileDownloader downloader = new FileDownloader(url);
+
+
+ ConnectionManager cm = new ConnectionManagerImpl();
+ downloader.setConnectionManager(cm);
+
+ downloader.setListener(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ 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/group04/349184132/Study/src/com/coderising/download/api/Connection.java b/group04/349184132/Study/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.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/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1599be1296
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+ public ConnectionException(String string) {
+ // TODO 自动生成的构造函数存根
+ }
+
+
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..bf9807b307
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..3ad903146b
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,52 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+ private HttpURLConnection conn ;
+ public ConnectionImpl(HttpURLConnection conn) {
+ this.conn = conn;
+ }
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+ conn.setRequestMethod("GET");
+ conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+ conn.setConnectTimeout(5000);
+
+ InputStream is = conn.getInputStream();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ int length = 0;
+ byte[] buffer = new byte[1024];
+ while(-1 != ( length = is.read(buffer))){
+ bos.write(buffer,0,length);
+ }
+ bos.flush();
+ is.close();
+ bos.close();
+
+
+ return bos.toByteArray();
+ }
+
+ @Override
+ public int getContentLength() {
+
+ return conn.getContentLength();
+ }
+
+ @Override
+ public void close() {
+ if(conn!=null){
+ conn = null;
+ }
+ }
+
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..9132787cf8
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,37 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+ @Override
+ public Connection open(String url) throws ConnectionException {
+
+ URL u;
+ HttpURLConnection hc ;
+ try {
+ u = new URL(url);
+ hc = (HttpURLConnection) u.openConnection();
+ Connection conn = new ConnectionImpl(hc);;
+ return conn;
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+
+
+
+
+
+ }
+
+}
diff --git a/group04/349184132/Study/src/com/linked/Iterator.java b/group04/349184132/Study/src/com/linked/Iterator.java
new file mode 100644
index 0000000000..b2397b9aa7
--- /dev/null
+++ b/group04/349184132/Study/src/com/linked/Iterator.java
@@ -0,0 +1,7 @@
+package com.linked;
+
+public interface Iterator {
+ public boolean hasNext();
+ public Object next();
+
+}
diff --git a/group04/349184132/Study/src/com/linked/LinkedList.java b/group04/349184132/Study/src/com/linked/LinkedList.java
new file mode 100644
index 0000000000..44aba236b4
--- /dev/null
+++ b/group04/349184132/Study/src/com/linked/LinkedList.java
@@ -0,0 +1,388 @@
+package com.linked;
+
+import java.util.Objects;
+
+
+
+public class LinkedList implements List {
+
+ private Node head;
+
+ private int size = 0;
+
+ public LinkedList(){
+ this.head = new Node(null,null);
+ }
+
+ public boolean add(T o){
+
+ if(head.next == null){
+ Node element = new Node(o,null);
+ head.next = element;
+ size++;
+ return true;
+ }
+
+ Node current = head.next;
+ while(current != null){
+ if(current.next==null){
+ Node element = new Node(o,null);
+ current.next = element;
+ size++;
+ return true;
+ }
+ current = current.next;
+ }
+
+ return false;
+ }
+
+
+ private void rangeCheck(int index) {
+ if (index < -1 || index > size - 1)
+ throw new IndexOutOfBoundsException(" index ");
+ }
+ public boolean add(int index , T o){
+ rangeCheck(index);
+
+ Node node = getNode(index);
+ Node pre = getNode(index-1);
+ Node newNode = new Node(o,node);
+ pre.next = newNode;
+ size++;
+ return true;
+ }
+
+
+ private Node getNode(int index){
+ rangeCheck(index);
+ Node current = head.next;
+ int count = 0;
+ while(current!=null){
+ if(count==index){
+ return current;
+ }
+ count++;
+ current = current.next;
+ }
+ return null;
+ }
+
+ public T get(int index){
+ Node node = getNode(index);
+ return (T)node.data;
+ }
+ public T remove(int index){
+ rangeCheck(index);
+
+ Node pre = getNode(index-1);
+ Node cur = getNode(index);
+ Node next = cur.next;
+ pre.next = next;
+ cur.next = null;
+ size--;
+ return (T)cur.data;
+ }
+
+
+ public T remove(T o) {
+ int index = 0;
+ for (Node x = head.next; x != null; x = x.next) {
+ if (Objects.deepEquals(x.data, o)) {
+ return remove(index);
+ }
+ index++;
+ }
+ size--;
+
+ return null;
+ }
+
+ @Override
+ public T set(int index, T element) {
+ Node node = getNode(index);
+ node.data = element;
+
+ return (T)node.data;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+
+ return indexOf(o)!=-1;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ int index = 0;
+
+ for (Node x = head.next; x != null; x = x.next) {
+ if (Objects.deepEquals(x.data, o))
+ return index;
+ index++;
+ }
+ return -1;
+ }
+
+ @Override
+ public Object[] toArray() {
+ Object[] result = new Object[size];
+ int i = 0;
+ for(Node x = head.next; x != null; x = x.next){
+ result[i++] = x.data;
+ }
+ return null;
+ }
+
+ @Override
+ public void clear() {
+ for(Node cur = head.next;cur!=null;cur = cur.next){
+ Node x = cur;
+ x.data = null;
+ x.next = null;
+ }
+ head = null;
+ size = 0;
+ }
+
+
+ public int size(){
+ return size;
+ }
+ public boolean isEmpty() {
+ return size == 0;
+ }
+ public void addFirst(Object o){
+ Node newFirst = new Node(o,null);
+ Node oldFirst = head.next;
+ head.next = newFirst;
+ newFirst.next = oldFirst;
+ size++;
+ }
+ public void addLast(Object o){
+ Node last = getNode(size-1);
+ Node newLast = new Node(o,null);
+ last.next = newLast;
+ size++;
+ }
+ public T removeFirst(){
+ Node oldFirst = head.next;
+ Node nextNode = oldFirst.next;
+ head.next = nextNode;
+ size--;
+ return (T)oldFirst;
+ }
+ public T removeLast(){
+ Node x = getNode(size-2);//倒数第二个结点
+ Node last = x.next;
+ x.next = null;
+ size--;
+ return (T)last;
+ }
+ public Iterator iterator(){
+ return new LinkedListIterator();
+ }
+
+ private class LinkedListIterator implements Iterator {
+ int pos = 0;
+
+ @Override
+ public boolean hasNext() {
+ return pos < size;
+ }
+
+ @Override
+ public Object next() {
+ if (pos > size)
+ throw new IllegalArgumentException();
+ return get(pos++);
+ }
+ }
+
+
+
+ private static class Node{
+ Object data;
+ Node next;
+ private Node(Object data, Node next) {
+ this.data = data;
+ this.next = next;
+
+ }
+ }
+
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public Node reverseFor(Node head){
+ if(head==null){
+ return null;
+ }
+ Node pre = null;
+ Node curr = head;
+ Node next = head.next;
+ while(curr.next!=null){
+
+ head.next = pre;
+ pre = curr;
+ curr = curr.next;
+ next = next.next;
+ head = curr;
+ }
+ pre = null;
+ curr = null;
+ return head;
+ }
+ /**
+ * 递归写法
+ * @param node
+ * @return
+ */
+ public Node reverseRecursion(Node current){
+ if(current == null || current.next == null){
+ return current;
+ }
+ Node nextNode = current.next;
+ current = null;
+ Node reverseNode = reverseRecursion(current.next);
+ nextNode.next = current;
+
+
+ return reverseNode;
+
+ }
+
+ /**
+ * 删除一个单链表的前半部分
+ * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+ int delectLength = size/2;
+ for(int i=0;isize-length){
+ throw new IllegalArgumentException(i +" or "+length +" error");
+ }
+ for(int j=i;j101->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){
+ throw new NullPointerException("List is null");
+ }
+ int[] result = new int[list.size()];
+ int index = 0;
+ for(Iterator iter = list.iterator();iter.hasNext();){
+ int LinkIndex = (int)iter.next();
+ result[index] = (int)get(LinkIndex);
+ }
+ return result;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 从当前链表中中删除在list中出现的元素
+
+ * @param list
+ */
+
+ public void subtract(LinkedList list){
+ if(list == null){
+ throw new NullPointerException("List is null");
+ }
+ int index = 0;
+ for(Node cur = head.next ; cur !=null ; cur = cur.next){
+ for(Node newList = list.head.next ; newList != null; newList = newList.next ){
+ if(Objects.deepEquals(cur.data, newList.data)){
+ remove(index);
+ }
+ }
+ index++;
+ }
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues(){
+ for(Node current=head.next;current!=null;current=current.next){
+ Node nextNode = current.next;
+
+ if(current.data.equals(nextNode.data)){
+ Node nextNodeNext = nextNode.next;
+ if(nextNodeNext==null){
+ current.next = null;
+ }else{
+ current.next = nextNodeNext;
+ nextNode.next = null;
+ }
+ }
+ }
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
+ * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max) {
+ if (min + max > size && min == max) {
+ throw new IndexOutOfBoundsException("Arguement is Illegal");
+ }
+ int index = 0;
+ for (Node curr = head.next; curr != null; curr = curr.next) {
+ if(((int)curr.data>min) && ((int)curr.data {
+ public boolean add(T o);
+
+ public boolean add(int index, T o);
+
+ public T get(int index);
+
+ T set(int index, T element);
+
+ public T remove(int index);
+
+ public T remove(T o);
+
+ public int size();
+
+ public boolean isEmpty();
+
+ public Iterator iterator();
+
+ public boolean contains(Object o);
+
+ int indexOf(Object o);
+
+
+ Object[] toArray();
+
+ void clear();
+
+}
diff --git a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java
index 06944cd8b1..4acbbf8880 100644
--- a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java
+++ b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java
@@ -64,7 +64,7 @@ public void testFibonacci() {
public void testGetPrimes() {
int[] primes = {2,3,5,7,11,13,17,19};
int max = 23;
- Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(max));
+ Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(27));
}
@Test
diff --git a/group04/351121278/src/com/coding/download/DownloadThread.java b/group04/351121278/src/com/coding/download/DownloadThread.java
new file mode 100644
index 0000000000..e0b396a5e6
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/DownloadThread.java
@@ -0,0 +1,34 @@
+package com.coding.download;
+
+import com.coding.download.api.Connection;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class DownloadThread extends Thread{
+
+ Connection conn;
+ int startPos;
+ int endPos;
+ File file;
+
+ public DownloadThread(File file, Connection conn, int startPos, int endPos){
+ this.file = file;
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+ public void run(){
+ try {
+ System.out.println("DownloadThread.run");
+ byte[] buffer = conn.read(startPos, endPos);
+ RandomAccessFile raf = new RandomAccessFile(file, "rw");
+ raf.seek(startPos);
+ raf.write(buffer, 0, buffer.length);
+ raf.close();
+ } catch (IOException e) {
+ System.out.println("e = " + e.getMessage());
+ }
+ }
+}
diff --git a/group04/351121278/src/com/coding/download/FileDownloader.java b/group04/351121278/src/com/coding/download/FileDownloader.java
new file mode 100644
index 0000000000..13d24f5b2b
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/FileDownloader.java
@@ -0,0 +1,76 @@
+package com.coding.download;
+
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+
+import java.io.File;
+
+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 = null;
+ try {
+
+ conn = cm.open(this.url);
+ File file = new File("D:/test");
+ int length = conn.getContentLength();
+ for (int i=0; i<3; i++) {
+ new DownloadThread(file, conn, 0, length-1).start();
+ }
+
+ } catch (ConnectionException e) {
+ e.printStackTrace();
+ }finally{
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+
+
+
+ }
+
+ 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/group04/351121278/src/com/coding/download/FileDownloaderTest.java b/group04/351121278/src/com/coding/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..84fbc8afa2
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coding.download;
+
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+import com.coding.download.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(new DownloadListener() {
+ @Override
+ public void notifyFinished() {
+ 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/group04/351121278/src/com/coding/download/api/Connection.java b/group04/351121278/src/com/coding/download/api/Connection.java
new file mode 100644
index 0000000000..bd75d6cad0
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coding.download.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/group04/351121278/src/com/coding/download/api/ConnectionException.java b/group04/351121278/src/com/coding/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1f57f86606
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/ConnectionException.java
@@ -0,0 +1,10 @@
+package com.coding.download.api;
+
+public class ConnectionException extends Exception {
+
+ public ConnectionException(String exceptionMessage) {
+
+ }
+ public ConnectionException() {
+ }
+}
diff --git a/group04/351121278/src/com/coding/download/api/ConnectionManager.java b/group04/351121278/src/com/coding/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..1d1a83caf2
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coding.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/group04/351121278/src/com/coding/download/api/DownloadListener.java b/group04/351121278/src/com/coding/download/api/DownloadListener.java
new file mode 100644
index 0000000000..c41045b0e8
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coding.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..7d524ec4a0
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java
@@ -0,0 +1,50 @@
+package com.coding.download.impl;
+
+import com.coding.download.api.Connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+
+public class ConnectionImpl implements Connection {
+
+ private static final int THEAD_COUNT = 3;
+ private URL url;
+ private HttpURLConnection httpURLConnection;
+ private final int BUFFER_SIZE = 1024;
+
+ public ConnectionImpl(URL url) {
+ this.url = url;
+ }
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+ URLConnection urlConnection = url.openConnection();
+ httpURLConnection = (HttpURLConnection)urlConnection;
+ httpURLConnection.setRequestMethod("GET");
+ InputStream in = httpURLConnection.getInputStream();
+ ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
+ int len;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ while ((len = in.read(buffer)) != -1) {
+ byteOutputStream.write(buffer, startPos, len);
+ }
+ return byteOutputStream.toByteArray();
+ }
+
+ @Override
+ public int getContentLength() {
+ return httpURLConnection.getContentLength();
+ }
+
+ @Override
+ public void close() {
+ httpURLConnection.disconnect();
+ }
+
+}
diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..c07a0b545a
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,23 @@
+package com.coding.download.impl;
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+ URL urlObj;
+ try {
+ urlObj = new URL(url);
+ } catch (MalformedURLException e) {
+ throw new ConnectionException("URL无法访问" + e.getMessage());
+ }
+ return new ConnectionImpl(urlObj);
+ }
+
+}
diff --git a/group04/474772605/.classpath b/group04/474772605/.classpath
index 28e2b79383..8d7ead9fe8 100644
--- a/group04/474772605/.classpath
+++ b/group04/474772605/.classpath
@@ -1,7 +1,11 @@
+
+
+
+
diff --git a/group04/474772605/jsp/homepage.jsp b/group04/474772605/jsp/homepage.jsp
new file mode 100644
index 0000000000..83fa84db7d
--- /dev/null
+++ b/group04/474772605/jsp/homepage.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+homepage
+
+
+
+
+
\ No newline at end of file
diff --git a/group04/474772605/jsp/showLogin.jsp b/group04/474772605/jsp/showLogin.jsp
new file mode 100644
index 0000000000..1e6cda01b1
--- /dev/null
+++ b/group04/474772605/jsp/showLogin.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+showLogin
+
+
+
+
+
\ No newline at end of file
diff --git a/group12/382266293/src/com/coderising/action/LoginAction.java b/group04/474772605/src/com/coderising/action/LoginAction.java
similarity index 95%
rename from group12/382266293/src/com/coderising/action/LoginAction.java
rename to group04/474772605/src/com/coderising/action/LoginAction.java
index b1224eb80d..69ad2750c0 100644
--- a/group12/382266293/src/com/coderising/action/LoginAction.java
+++ b/group04/474772605/src/com/coderising/action/LoginAction.java
@@ -1,39 +1,40 @@
-package com.coderising.action;
-
-/**
- * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
- * @author liuxin
- *
- */
-public class LoginAction{
- private String name ;
- private String password;
- private String message;
-
- public String getName() {
- return name;
- }
-
- public String getPassword() {
- return password;
- }
-
- public String execute(){
- if("test".equals(name) && "1234".equals(password)){
- this.message = "login successful";
- return "success";
- }
- this.message = "login failed,please check your user/pwd";
- return "fail";
- }
-
- public void setName(String name){
- this.name = name;
- }
- public void setPassword(String password){
- this.password = password;
- }
- public String getMessage(){
- return this.message;
- }
-}
\ No newline at end of file
+package com.coderising.action;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/group04/474772605/src/com/coderising/action/LogoutAction.java b/group04/474772605/src/com/coderising/action/LogoutAction.java
new file mode 100644
index 0000000000..10e4eb37c7
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/LogoutAction.java
@@ -0,0 +1,40 @@
+package com.coderising.action;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LogoutAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success1";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/group04/474772605/src/com/coderising/action/Struts.java b/group04/474772605/src/com/coderising/action/Struts.java
new file mode 100644
index 0000000000..7db0e4687f
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/Struts.java
@@ -0,0 +1,122 @@
+package com.coderising.action;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Attribute;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+
+
+public class Struts {
+
+
+
+ public static void main(String[] args) throws DocumentException {
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+ View view = Struts.runAction(actionName,params);
+ System.out.println(view.getJsp());
+ System.out.println(view.getParameters());
+ }
+
+
+ public static View runAction(String actionName, Map parameters) {
+ View view = new View();
+ SAXReader reader = new SAXReader();
+ //读取文件 转换成Document
+ org.dom4j.Document document;
+ try {
+ document = reader.read(new File("src/struts.xml"));
+ Element root = document.getRootElement();
+ @SuppressWarnings("unchecked")
+ List elements = root.elements();
+ for (Element element : elements) {
+ Attribute actionAttribute = element.attribute("name");
+ Attribute classAttribute = element.attribute("class");
+ if(actionName.equals(actionAttribute.getValue())){
+ String clazz = null;
+ clazz = classAttribute.getValue();
+ Object o = Class.forName(clazz).newInstance();
+ for (Map.Entry entry : parameters.entrySet()) {
+ String name = entry.getKey();
+ String value =entry.getValue();
+ String methodname = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
+ Method m = o.getClass().getMethod(methodname, String.class);
+ m.invoke(o, value);
+
+ }
+ Method m3 = o.getClass().getMethod("execute");
+ String result = (String) m3.invoke(o);
+ String jspPath = null;
+ List element1s = element.elements("result");
+ if(result.equals("success")){
+ for (int i = 0; i < element1s.size(); i++) {
+ Attribute attribute2 = element1s.get(i).attribute("name");
+ if (attribute2.getValue().equals("success")) {
+ jspPath = element1s.get(i).getStringValue();
+ }
+ }
+ }else if(result.equals("fail")){
+ for (int i = 0; i < element1s.size(); i++) {
+ Attribute attribute2 = element1s.get(i).attribute("name");
+ if (attribute2.getValue().equals("fail")) {
+ jspPath = element1s.get(i).getStringValue();
+ }
+ }
+ }
+ HashMapviewparamterHashMap = new HashMap();
+ Method[]methods = o.getClass().getMethods();
+ String methodname;
+ for (int j = 0; j < o.getClass().getMethods().length; j++) {
+ methodname = methods[j].getName();
+ if(methodname.startsWith("get")&&!methodname.equals("getClass")){
+ String methodname1 = methods[j].getName();
+ methodname1 = methodname.substring(3,4).toUpperCase()+methodname1.substring(4);
+ viewparamterHashMap.put(methodname1, methods[j].invoke(o));
+ }
+ }
+ view.setJsp(jspPath);
+ view.setParameters(viewparamterHashMap);
+ return view;
+ }
+ }
+ } catch (Exception e) {
+ // TODO: handle exception
+ }
+ return null;
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+
+
+ }
+
+}
diff --git a/group04/474772605/src/com/coderising/action/StrutsTest.java b/group04/474772605/src/com/coderising/action/StrutsTest.java
new file mode 100644
index 0000000000..c161c0f932
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.action;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "com.coderising.action.LoginAction";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/group04/474772605/src/com/coderising/action/View.java b/group04/474772605/src/com/coderising/action/View.java
new file mode 100644
index 0000000000..11cb1872e5
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/View.java
@@ -0,0 +1,23 @@
+package com.coderising.action;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/group04/474772605/src/com/coderising/action/struts.xml b/group04/474772605/src/com/coderising/action/struts.xml
new file mode 100644
index 0000000000..a6cfe43e6c
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/struts.xml
@@ -0,0 +1,11 @@
+
+
+
+ /jsp/homepage.jsp
+ /jsp/showLogin.jsp
+
+
+ /jsp/welcome.jsp
+ /jsp/error.jsp
+
+
\ No newline at end of file
diff --git a/group04/474772605/src/com/coderising/array/ArrayUtil.java b/group04/474772605/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..ddb00c17b6
--- /dev/null
+++ b/group04/474772605/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,146 @@
+package com.coderising.array;
+
+import java.util.ArrayList;
+import java.util.Stack;
+
+import com.coding.basic.LinkedList;
+
+public class ArrayUtil {
+
+ /**
+ * 给定一个整形数组a , 对该数组的值进行置换
+ 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7]
+ 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+ * @param origin
+ * @return
+ */
+ public void reverseArray(int[] origin){
+ Stack stack = new Stack();
+ for (int i = 0; i < origin.length; i++) {
+ stack.add(origin[i]);
+ }
+
+ for (int j = 0; j < stack.size(); j++) {
+ origin[j] = (Integer) stack.pop();
+ }
+
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public int[] removeZero(int[] oldArray){
+ ArrayList newarray = new ArrayList();
+ for (int i = 0; i < oldArray.length; i++) {
+ if(0!=oldArray[i]){
+ newarray.add(oldArray[i]);
+ }
+ }
+ int result [] = new int [newarray.size()];
+ for (int j = 0; j < result.length; j++) {
+ result[j]=newarray.get(j);
+ }
+
+ return result;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的
+ * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public int[] merge(int[] array1, int[] array2){
+ ArrayList newarray = new ArrayList();
+ for (int i = 0; i < array1.length; i++) {
+ newarray.add(i, array1[i]);
+ }
+ for (int j = 0; j < array2.length; j++) {
+ if (newarray.get(j)>array2[j]&&newarray.get(j+1)>array2[j]) {
+ newarray.add(j+1, array2[j]);
+ }
+ }
+
+ int result [] = new int [newarray.size()];
+ for (int z = 0; z < result.length; z++) {
+ result[z]=newarray.get(z);
+ }
+ return result;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+ ArrayList newarray = new ArrayList();
+ for (int i = 0; i < oldArray.length; i++) {
+ newarray.add(i, oldArray[i]);
+ }
+ while (newarray.size()='A'&&(char)num <='z'){
+ n1++;
+ }
+ if((char)num >='A'&&(char)num <='Z'){
+ n2++;
+ }
+ }
+ }
+ reader.close();
+ System.out.println(n1+""+n2);
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+
+
+ public float method(){
+ return 13.21f;
+ }
+
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
diff --git a/group04/474772605/src/com/coding/iostreams/test.java b/group04/474772605/src/com/coding/iostreams/test.java
new file mode 100644
index 0000000000..1bd474ca7b
--- /dev/null
+++ b/group04/474772605/src/com/coding/iostreams/test.java
@@ -0,0 +1,14 @@
+package com.coding.iostreams;
+
+public interface test {
+ public float method();
+
+}
+
+
+
+
+
+
+
+
diff --git a/group04/349184132/Study/bin/com/second/struts.xml b/group04/474772605/src/struts.xml
similarity index 57%
rename from group04/349184132/Study/bin/com/second/struts.xml
rename to group04/474772605/src/struts.xml
index 554dbbe227..8bd00bb1f0 100644
--- a/group04/349184132/Study/bin/com/second/struts.xml
+++ b/group04/474772605/src/struts.xml
@@ -1,11 +1,11 @@
-
+
/jsp/homepage.jsp
/jsp/showLogin.jsp
-
+
/jsp/welcome.jsp
- /jsp/error.jsp
+ /jsp/error.jsp
\ No newline at end of file
diff --git a/group04/474772605/test/Test.java b/group04/474772605/test/Test.java
new file mode 100644
index 0000000000..8c0f62930b
--- /dev/null
+++ b/group04/474772605/test/Test.java
@@ -0,0 +1,50 @@
+
+
+ import java.io.File;
+ import java.io.FileInputStream;
+ import java.io.InputStreamReader;
+ import java.io.Reader;
+
+
+
+
+ public class Test{
+ static int n1 =0 ;
+ static int n2 =0 ;
+
+ public static void main(String[] args) throws Exception{
+
+ Test.readFileByChars("D://Text.txt");
+
+ System.out.println("字母个数为:"+n1+" 字母个数为"+n2);
+
+ }
+
+ public static void readFileByChars(String fileName) {
+ File file = new File(fileName);
+ Reader reader = null;
+ try {
+ System.out.println("以字符为单位读取文件内容,一次读一个字节:");
+ // 一次读一个字符
+ reader = new InputStreamReader(new FileInputStream(file));
+ int tempchar;
+ while ((tempchar = reader.read()) != -1) {
+ // 对于windows下,\r\n这两个字符在一起时,表示一个换行。
+ // 但如果这两个字符分开显示时,会换两次行。
+ // 因此,屏蔽掉\r,或者屏蔽\n。否则,将会多出很多空行。
+ if (((char) tempchar) != '\r') {
+ System.out.print((char) tempchar);
+ n1++;
+ if((char)tempchar >='A'&&(char)tempchar<='Z'){
+ n2++;
+ }
+
+ }
+ }
+ reader.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
diff --git a/group04/474772605/test/com/coding/basic/Heros.java b/group04/474772605/test/com/coding/basic/Heros.java
new file mode 100644
index 0000000000..878204aede
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/Heros.java
@@ -0,0 +1,51 @@
+package com.coding.basic;
+
+import java.lang.reflect.Method;
+
+public class Heros {
+ private String name;//名字
+ private String type;//类型
+ private int camp;//0,近卫;1,天灾
+ public Heros(){
+
+ }
+ /*
+ public Heros(String name, String type, int camp) {
+
+ super();
+
+ this.name = name;
+ this.type = type;
+ this.camp = camp;
+ }*/
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public int getCamp() {
+ return camp;
+ }
+
+ public void setCamp(int camp) {
+ this.camp = camp;
+ }
+
+ @Override
+ public String toString() {
+ return "Heros [\n name=" + name + ", \n type=" + type + ", \n camp=" + camp + "\n]";
+ }
+
+}
\ No newline at end of file
diff --git a/group04/474772605/test/com/coding/basic/Test.java b/group04/474772605/test/com/coding/basic/Test.java
new file mode 100644
index 0000000000..97f7254c82
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/Test.java
@@ -0,0 +1,43 @@
+package com.coding.basic;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class Test {
+
+ public static void main(String args[]) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ Foo foo = new Foo("这个一个Foo对象!");
+ Class clazz = foo.getClass();
+ Field[] abc =clazz.getDeclaredFields();
+
+ // Object value = getFieldValueByName(key, obj);
+ Method m1 = clazz.getDeclaredMethod("outInfo");
+ Method m2 = clazz.getDeclaredMethod("setMsg", String.class);
+ Method m3 = clazz.getDeclaredMethod("getMsg");
+ m1.invoke(foo);
+ m2.invoke(foo, "重新设置msg信息!");
+ String msg = (String) m3.invoke(foo);
+ System.out.println(msg);
+ }
+}
+
+class Foo {
+ private String msg;
+
+ public Foo(String msg) {
+ this.msg = msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void outInfo() {
+ System.out.println("这是测试Java反射的测试类");
+ }
+}
diff --git a/group04/474772605/test/com/coding/basic/TestStack.java b/group04/474772605/test/com/coding/basic/TestStack.java
new file mode 100644
index 0000000000..e4caa84d98
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/TestStack.java
@@ -0,0 +1,35 @@
+package com.coding.basic;
+
+import junit.framework.TestCase;
+
+public class TestStack extends TestCase{
+private Stack stack;
+
+
+public void setUp() throws Exception {
+ stack = new Stack();
+
+}
+
+public void testpop(){
+// Stack stack = new Stack();
+ Object o = null ;
+ try {
+ stack.push(o);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+
+}
+
+
+
+
+
+
+
+}
diff --git a/group04/474772605/test/com/coding/basic/Testarray.java b/group04/474772605/test/com/coding/basic/Testarray.java
new file mode 100644
index 0000000000..19edb9f85d
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/Testarray.java
@@ -0,0 +1,22 @@
+package com.coding.basic;
+
+import junit.framework.TestCase;
+
+public class Testarray extends TestCase{
+
+ public void testararry(){
+ Throwable tx = null;
+ try {
+ ArrayList n = new ArrayList();
+ Object o = null ;
+
+ n.add(o);
+ fail();
+ } catch (Exception e) {
+ tx =e;
+ assertEquals(Exception.class, tx.getClass());
+ assertEquals("对象不能为空", e.getMessage());
+ }
+ }
+
+}
diff --git a/group04/474772605/test/com/coding/basic/teest.java b/group04/474772605/test/com/coding/basic/teest.java
new file mode 100644
index 0000000000..e8004c14b6
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/teest.java
@@ -0,0 +1,24 @@
+package com.coding.basic;
+
+import java.lang.reflect.Method;
+
+public class teest {
+ public static void main(String[] args) {
+ Class> herosClass = Heros.class;
+ try {
+ Method m1 = herosClass.getMethod("setName",String.class);
+ Method m3 = herosClass.getMethod("setCamp",int.class);
+ Method m2 = herosClass.getMethod("getName");
+
+
+ Object userInfo = herosClass.newInstance();
+ System.out.println("调用构造函数:"+userInfo);
+ m1.invoke(userInfo,"影魔");
+ m3.invoke(userInfo, 1);
+ System.out.println("调用set方法:"+userInfo);
+ System.out.println("调用get方法:"+m2.invoke(userInfo));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..d4e0f52537
--- /dev/null
+++ b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,83 @@
+package com.coderising.jvm.loader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+
+
+public class ClassFileLoader {
+
+ private static final String CLASS_SUFFIX = ".class";
+ private static final byte[] EMPTY_BYTES = new byte[0];
+ private List clzPaths = new ArrayList();
+
+ public byte[] readBinaryCode(String className) {
+ if(StringUtils.isEmpty(className)) {
+ return EMPTY_BYTES;
+ }
+ String child = className.replaceAll("\\.", "\\\\") + CLASS_SUFFIX;
+ for (String parent: clzPaths) {
+ File file = new File(parent, child);
+ if(file.exists()) {
+ return doReadBinaryCode(file);
+ }
+ }
+ return EMPTY_BYTES;
+ }
+
+
+ private byte[] doReadBinaryCode(File file) {
+ FileInputStream fis = null;
+ ByteArrayOutputStream baos = null;
+ try {
+ fis = new FileInputStream(file);
+ baos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int len = 0;
+ while((len = fis.read(b)) > 0) {
+ baos.write(b, 0, len);
+ }
+ return baos.toByteArray();
+ } catch (Exception e) {
+ new RuntimeException(e);
+ } finally {
+ close(baos);
+ close(fis);
+ }
+ return EMPTY_BYTES;
+ }
+
+
+ private void close(Closeable stream) {
+ if(stream != null ) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void addClassPath(String path) {
+ clzPaths.add(path);
+ }
+
+ public String getClassPath(){
+ StringBuilder builder = new StringBuilder();
+ for (String path : clzPaths) {
+ builder.append(path).append(";");
+ }
+ if(builder.length() > 0) {
+ builder = builder.deleteCharAt(builder.length() - 1);
+ }
+ return builder.toString();
+ }
+
+}
diff --git a/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..3f4a585db7
--- /dev/null
+++ b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,93 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+
+ private static final String CAFEBABE = "cafebabe";
+ static String path1 = "D:\\Dev\\git_repository\\coding2017\\group04\\498654356\\mini-jvm\\jvm\\target\\test-classes";
+ static String path2 = "C:\\temp";
+
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testClassPath(){
+
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+ loader.addClassPath(path2);
+
+ String clzPath = loader.getClassPath();
+
+ Assert.assertEquals(path1+";"+path2,clzPath);
+
+ }
+
+ @Test
+ public void testClassFileLength() {
+
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+
+ String className = "com.coderising.jvm.test.EmployeeV1";
+
+ byte[] byteCodes = loader.readBinaryCode(className);
+
+ // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大
+ Assert.assertEquals(1056, byteCodes.length);
+
+ }
+
+
+ @Test
+ public void testMagicNumber(){
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+ String className = "com.coderising.jvm.test.EmployeeV1";
+ byte[] byteCodes = loader.readBinaryCode(className);
+ byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+
+
+ String acctualValue = this.byteToHexString(codes);
+
+ Assert.assertEquals(CAFEBABE, acctualValue);
+ }
+
+
+
+
+
+
+ private String byteToHexString(byte[] codes ){
+ StringBuffer buffer = new StringBuffer();
+ for(int i=0;i size) {
+ return Arrays.copyOf(baos.toByteArray(), size);
+ }
+ return baos.toByteArray();
+ }
+
+ @Override
+ public int getContentLength() {
+ try {
+ return url.openConnection().getContentLength();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return -1;
+ }
+
+ @Override
+ public void close() {
+ try {
+ url.openStream().close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..e595cb3ccb
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,14 @@
+package org.coding.three.download.impl;
+
+import org.coding.three.download.api.Connection;
+import org.coding.three.download.api.ConnectionException;
+import org.coding.three.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+ return new ConnectionImpl(url);
+ }
+
+}
diff --git a/group04/498654356/one/src/org/coding/three/list/List.java b/group04/498654356/one/src/org/coding/three/list/List.java
new file mode 100644
index 0000000000..d06cf962da
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/list/List.java
@@ -0,0 +1,9 @@
+package org.coding.three.list;
+
+public interface List {
+ public void add(Object o);
+ public void add(int index, Object o);
+ public Object get(int index);
+ public Object remove(int index);
+ public int size();
+}
diff --git a/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java
new file mode 100644
index 0000000000..ef38ca811d
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java
@@ -0,0 +1,422 @@
+package org.coding.three.list.impl;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.coding.three.list.List;
+/**
+ * 单链表/单向链表
+ */
+public class LinkedList implements List {
+ /**
+ * 0. head 节点存储数据
+ * 1. 这里的 head 第一次添加之后 "引用" 将不再改变;"值" 可以被修改已表示往首节点插入新的值。
+ * 2. 可以将 head 修改为对 node 引用, 不存储任何数据。
+ */
+ private Node head;
+
+ public void add(Object o){
+ Node node = new Node(o);
+ if(head == null){ //第一次
+ head = node;
+ } else {
+ getNode(size() - 1).next = node;
+ }
+ }
+
+ private Node getNode(int index) {
+ checkIndex(index);
+ Node node = head;
+ for(int i = 0; i < index; i++) {
+ node = node.next;
+ }
+ return node;
+ }
+
+ private void checkIndex(int index) {
+ int size = size();
+ if(index < 0 || index > (size - 1)) {
+ throw new IndexOutOfBoundsException("size = " + size + ", index = " + index);
+ }
+ }
+ public void add(int index , Object o){
+ checkIndex(index);
+ if(index == 0) { //更新 head 的值, 将旧值创建新的Node插入到 head 后
+ Object data = head.data;
+ head.data = o;
+ Node node = new Node(data);
+ node.next = head.next;
+ head.next = node;
+ } else {
+ Node pre = getNode(index - 1);
+ Node node = new Node(o);
+ node.next = pre.next;
+ pre.next = node;
+ }
+ }
+ public Object get(int index){
+ checkIndex(index);
+ return getNode(index).data;
+ }
+ public Object remove(int index){
+ checkIndex(index);
+ Object data = null;
+ if(index == 0) {
+ Node next = head.next;
+ data = head.data;
+ if(next == null) {
+ head = null;
+ } else {
+ head.data = next.data;
+ head.next = next.next;
+ next.next = null;
+ }
+ } else {
+ Node pre = getNode(index - 1);
+ Node node = pre.next;
+ pre.next = node.next;
+ node.next = null;
+ data = node.data;
+ }
+ return data;
+ }
+
+ public int size(){
+ Node temp = head;
+ int size = 0;
+ while(temp != null) {
+ size++;
+ temp = temp.next;
+ }
+ return size;
+ }
+
+ public void addFirst(Object o){
+ add(0, o);
+ }
+ public void addLast(Object o){
+ add(o);
+ }
+ public Object removeFirst(){
+ return remove(0);
+ }
+ public Object removeLast(){
+ return remove(size() - 1);
+ }
+ public Iterator> iterator(){
+ return new LinkedIterator();
+ }
+
+ class LinkedIterator implements Iterator