diff --git a/group01/1298552064/src/week04/lru/LRUPageFrame.java b/group01/1298552064/src/week04/lru/LRUPageFrame.java new file mode 100644 index 0000000000..b00ff2c116 --- /dev/null +++ b/group01/1298552064/src/week04/lru/LRUPageFrame.java @@ -0,0 +1,116 @@ +package week04.lru; + +public class LRUPageFrame { + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(Node prev, Node next, int pageNum) { + this.prev = prev; + this.next = next; + this.pageNum = pageNum; + } + } + + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + private int size; // 链表长度 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + int index = find(pageNum); + if (size != 0) { + if(index >= 0){ + remove(index); + }else if(size == capacity){ + remove(size - 1); + } + } + addToHead(pageNum); + } + + public void remove(int index) { + if (index == 0) { + if(size == 1){ + first = last = null; + }else{ + first = first.next; + first.prev = null; + } + } else if (index == (size - 1)) { + if(size == 1){ + first = last = null; + }else{ + last = last.prev; + last.next = null; + } + } else { + Node node = first; + for (int i = 1; i < index; i++) { + node = node.next; + } + + Node nxt = node.next; + + node.next = nxt.next; + (nxt.next).prev = node; + nxt = null; + } + size--; + } + + public int find(int pageNum) { + int index = 0; + Node cur = first; + while (cur != null) { + if (pageNum == cur.pageNum) { + return index; + } + cur = cur.next; + index++; + } + return -1; + } + + public void addToHead(int pageNum) { + // 链表为空 + if (first == null) { + Node node = new Node(null, null, pageNum); + first = node; + last = node; + } else { + Node node = new Node(null,first,pageNum); + first.prev = node; + first = node; + } + size ++; + } + + @Override + 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/group01/1298552064/src/week04/minijvm/loader/ClassFileLoader.java b/group01/1298552064/src/week04/minijvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..2e80e89587 --- /dev/null +++ b/group01/1298552064/src/week04/minijvm/loader/ClassFileLoader.java @@ -0,0 +1,67 @@ +package week04.minijvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + if(className == null){ + return null; + } + + boolean isFileExist = false; + File file = null; + String classPath = className.replace(".", "\\"); + for(int i = 0 ; i < clzPaths.size(); i++){ + String basePath = clzPaths.get(i); + file = new File(basePath + File.separator + classPath + ".class"); + + if(file.exists()){ + isFileExist = true; + break; + } + } + + //找不到类 + if(!isFileExist){ + throw new FileNotFoundException(); + } + + //读取字节码文件到数组 + FileInputStream in = new FileInputStream(file); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte [] rs = new byte[1024]; + int len = 0; + while((len = in.read(rs)) != -1){ + bos.write(rs, 0, len); + } + bos.close(); + in.close(); + System.out.println("readBinaryCode:" + " file size = " + file.length()); + return bos.toByteArray(); + } + + public void addClassPath(String path) { + if(! clzPaths.contains(path)){ + clzPaths.add(path); + } + } + + public String getClassPath() { + StringBuffer buffer = new StringBuffer(); + for(int i = 0;i < clzPaths.size();i++){ + buffer.append(clzPaths.get(i)); + if(i != clzPaths.size() - 1){ + buffer.append(";"); + } + } + return buffer.toString(); + } +} diff --git a/group01/1298552064/src/week04/test/ClassFileloaderTest.java b/group01/1298552064/src/week04/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..18b42f859d --- /dev/null +++ b/group01/1298552064/src/week04/test/ClassFileloaderTest.java @@ -0,0 +1,78 @@ +package week04.test; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import week04.minijvm.loader.ClassFileLoader; + + +public class ClassFileloaderTest { + static String path1 = "D:\\Git_2017\\coding2017\\group01\\1298552064\\bin"; + 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() throws IOException { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "week04.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1032, byteCodes.length); + + } + + @Test + public void testMagicNumber() throws IOException { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "week04.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 < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group01/1298552064/src/week04/test/EmployeeV1.java b/group01/1298552064/src/week04/test/EmployeeV1.java new file mode 100644 index 0000000000..1c292f7744 --- /dev/null +++ b/group01/1298552064/src/week04/test/EmployeeV1.java @@ -0,0 +1,30 @@ +package week04.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} diff --git a/group01/1298552064/src/week04/test/LRUPageFrameTest.java b/group01/1298552064/src/week04/test/LRUPageFrameTest.java new file mode 100644 index 0000000000..6fbf3ddef9 --- /dev/null +++ b/group01/1298552064/src/week04/test/LRUPageFrameTest.java @@ -0,0 +1,29 @@ +package week04.test; + +import org.junit.Assert; +import org.junit.Test; + +import week04.lru.LRUPageFrame; + +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/group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/loader/ClassFileLoader.java b/group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..7528e27324 --- /dev/null +++ b/group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/loader/ClassFileLoader.java @@ -0,0 +1,74 @@ +package com.coding2017.week4.jvm.loader; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + private static Joiner SEMICOLON_JOINER = Joiner.on(";").skipNulls(); + private static Splitter DOT_SPLITTER = Splitter.on(".").trimResults(); + private static Joiner SLASH_JOINER = Joiner.on("/").skipNulls(); + + private static String CLASS_SUFFIX = ".class"; + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + List list = DOT_SPLITTER.splitToList(className); + String childDirectory = SLASH_JOINER.join(list); + for (String clzPath : clzPaths) { + String fullPath = makeFullPath(clzPath, childDirectory); + if (fileExist(fullPath)) { + return readFileBytes(fullPath); + } + } + System.out.println("no this class file: " + className); + return null; + } + + private byte[] readFileBytes(String filePath) { + try { + File file = new File(filePath); + long length = file.length(); + byte[] fileBytes = new byte[(int) length]; + int readLength = new FileInputStream(filePath).read(fileBytes); + if (readLength != length) { + System.out.println("read file error. read length: " + readLength + ", full length : " + length); + return null; + } + return fileBytes; + } catch (IOException e) { + System.out.println("read file error. " + filePath); + return null; + } + } + + private boolean fileExist(String fullPath) { + File classFile = new File(fullPath); + return classFile.exists() && classFile.isFile(); + } + + private String makeFullPath(String clzPath, String childDirectory) { + if (clzPath.endsWith("/") || clzPath.endsWith("\\")) { + return clzPath + childDirectory + CLASS_SUFFIX; + } else { + return clzPath + "/" + childDirectory + CLASS_SUFFIX; + } + } + + public void addClassPath(String path) { + if (!clzPaths.contains(path)) { + clzPaths.add(path); + } + } + + public String getClassPath() { + return SEMICOLON_JOINER.join(clzPaths); + } + +} diff --git a/group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/test/EmployeeV1.java b/group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..7d0419dc77 --- /dev/null +++ b/group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/test/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.coding2017.week4.jvm.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group01/280646174/basic/src/main/java/com/coding2017/week4/lru/LRUPageFrame.java b/group01/280646174/basic/src/main/java/com/coding2017/week4/lru/LRUPageFrame.java new file mode 100644 index 0000000000..55039dda56 --- /dev/null +++ b/group01/280646174/basic/src/main/java/com/coding2017/week4/lru/LRUPageFrame.java @@ -0,0 +1,131 @@ +package com.coding2017.week4.lru; + +/** + * 用双向链表实现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;// 链表尾 + private int size; // 当前个数 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + size = 0; + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + Node node = query(pageNum); + if (node == null) { + Node newNode = new Node(); + newNode.pageNum = pageNum; + accessNotExist(newNode); + } else { + accessExist(node); + } + } + + private void accessExist(Node node) { + removeNode(node); + addFirst(node); + } + + /** + * 此处没有要求传入的node的prev和next, 所以需要自己处理 + * + * @param node + */ + private void addFirst(Node node) { + node.prev = null; + node.next = null; + if (first == null) { + first = node; + last = node; + } else { + first.prev = node; + node.next = first; + first = node; + } + size++; + } + + /** + * 需要考虑删除的节点是头结点, 或尾节点的情况 + */ + private void removeNode(Node node) { + if (node.prev == null) { + first = node.next; + } + if (node.next == null) { + last = node.prev; + } + if (node.prev != null) { + node.prev.next = node.next; + } + if (node.next != null) { + node.next.prev = node.prev; + } + size--; + } + + /** + * 如果已经满了, 则挤出去一个, 然后追加 + * + * @param node + */ + private void accessNotExist(Node node) { + if (size == capacity) { + removeLast(); + } + addFirst(node); + } + + private void removeLast() { + last.prev.next = null; + last = last.prev; + size--; + } + + private Node query(int pageNum) { + for (Node node = first; node != null; node = node.next) { + if (pageNum == node.pageNum) { + return node; + } + } + return null; + } + + 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/group01/280646174/basic/src/test/java/com/coding2017/week4/jvm/loader/ClassFileLoaderTest.java b/group01/280646174/basic/src/test/java/com/coding2017/week4/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..a9c118e20b --- /dev/null +++ b/group01/280646174/basic/src/test/java/com/coding2017/week4/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,81 @@ +package com.coding2017.week4.jvm.loader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by kaitao.li on 2017/4/3. + */ +public class ClassFileLoaderTest { + + static String path1 = "/Users/kaitao.li/code/study/coding2017/group01/280646174/basic/target/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.coding2017.week4.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1068, byteCodes.length); + + } + + @Test + public void testMagicNumber() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coding2017.week4.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 < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + +} \ No newline at end of file diff --git a/group01/280646174/basic/src/test/java/com/coding2017/week4/lru/LRUPageFrameTest.java b/group01/280646174/basic/src/test/java/com/coding2017/week4/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..ede685b83c --- /dev/null +++ b/group01/280646174/basic/src/test/java/com/coding2017/week4/lru/LRUPageFrameTest.java @@ -0,0 +1,34 @@ +package com.coding2017.week4.lru; + +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by kaitao.li on 2017/4/3. + */ +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()); + } + +} \ No newline at end of file diff --git a/group01/349209948/src/week2_0305/array/ArrayUtil.java b/group01/349209948/src/week2_0305/array/ArrayUtil.java new file mode 100644 index 0000000000..3158becf66 --- /dev/null +++ b/group01/349209948/src/week2_0305/array/ArrayUtil.java @@ -0,0 +1,246 @@ +package week2_0305.array; + +import java.util.ArrayList; + +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){ + if (origin == null) { + throw new IllegalArgumentException(); + } + int temp = 0; + for (int i = 0; i< origin.length/2; i++) { + temp = origin[i]; + origin[i] = origin[origin.length - i]; + origin[origin.length - 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 int[] removeZero(int[] oldArray){ + if (oldArray == null) { + throw new IllegalArgumentException(); + } + int[] newArray = new int[oldArray.length]; + int index = 0; + for (int i =0; i < oldArray.length; i ++){ + if (oldArray[i] == 0) { + continue; + } else { + newArray[index++] = oldArray[i]; + } + } + return copyOf(newArray, index); + } + + /** + * 给定两个已经排序好的整形数组, 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){ + if (array1 == null || array2 == null) { + throw new IllegalArgumentException(); + } + int[] array3 = new int[array1.length + array2.length]; + int index1 = 0; + int index2 = 0; + int actualSize = 0; + for (int i = 0; i < array3.length; i ++) { + //把array2剩余的部分拷入数据 + if (index1 >= array1.length) { + arrayCopy(array2, index2, array3, i, array2.length - index2); + actualSize = i + array2.length - index2; + return copyOf(array3, actualSize); + } + if (index2 >= array2.length) { + arrayCopy(array1, index1, array3, i, array1.length - index1); + actualSize = i + array1.length - index1; + return copyOf(array3, actualSize); + } + if (array1[index1] < array2[index2]) { + array3[i] = array1[index1]; + index1 ++; + } else if (array1[index1] == array2[index2]) { + array3[i] = array1[index1]; + index1 ++; + index2 ++; + } else { + array3[i] = array2[index2]; + index2 ++; + } + } + // array1 he array2 均为 空数组的情况 + return new int[0]; + } + + private void arrayCopy(int[] src, int srcPos, int[] dest, int destPos, int length) { + for (int i = 0; i< length; i++) { + dest[destPos++] = src[srcPos++]; + } + } + + private int[] copyOf(int[] arr, int size) { + int[] dest = new int[size]; + for (int i = 0; i< size; i++) { + dest[i] = arr[i]; + } + return dest; + } + /** + * 把一个已经存满数据的数组 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){ + if (oldArray == null || size <0) { + throw new IllegalArgumentException(); + } + int[] newArray = new int[oldArray.length + size]; + for (int i = 0; i < oldArray.length; i++) { + newArray[i] = oldArray[i]; + } + 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 int[] fibonacci(int max){ + if (max < 0 ) { + throw new IllegalArgumentException(); + } else if (max == 1) { + return new int[0]; + } + ArrayList list = new ArrayList(); + list.add(1); + list.add(1); + int i = 0; + while(true) { + int num = (int)list.get(i) + (int)list.get(i+1); + if (num < max) { + list.add(num); + } else { + break; + } + } + return listToArray(list); + } + + private int[] listToArray(ArrayList list){ + int[] arr = new int[list.size()]; + for (int i = 0;i < list.size(); i++) { + arr[i] = (int)list.get(i); + } + return arr; + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + if (max <2) { + throw new IllegalArgumentException(); + } + ArrayList list = new ArrayList(); + for (int i = 2; i < max; i++) { + if (isPrime(i)) { + list.add(i); + } + } + return listToArray(list); + } + + public boolean isPrime(int m) { + for (int i = 1; i < m/2; i++) { + if (m % i == 0) { + return false; + } + } + return true; + } + + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + if (max < 0) { + throw new IllegalArgumentException(); + } + ArrayList list = new ArrayList(); + for (int i = 0; i< max; i++) { + if (isPerfectNumber(i)) { + list.add(i); + } + } + return listToArray(list); + } + + public boolean isPerfectNumber(int num) { + int sum = 0; + for (int i = 0; i < num; i++) { + if (num % i == 0) { + sum += i; + } + } + if (sum == num) { + return true; + } else { + return false; + } + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + if (array == null) { + throw new IllegalArgumentException(); + } + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + builder.append(array[i]).append(seperator); + } + return builder.substring(0, builder.length() - seperator.length()); + } + + +} diff --git a/group01/349209948/src/week2_0305/litestruts/Configuration.java b/group01/349209948/src/week2_0305/litestruts/Configuration.java new file mode 100644 index 0000000000..a10ac1cef9 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/Configuration.java @@ -0,0 +1,95 @@ +package week2_0305.litestruts; + +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; +import week2_0305.litestruts.ConfigurationException;; + +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 (IOException e) { + throw new ConfigurationException(e); + } catch (JDOMException 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 actionName, String resultName) { + ActionConfig ac = this.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 actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + + public String getClassName() { + return this.clzName; + } + + public void addViewResult(String name, String viewName) { + viewResult.put(name, viewName); + } + + public String getViewName(String resultName) { + return viewResult.get(resultName); + } + } +} diff --git a/group01/349209948/src/week2_0305/litestruts/ConfigurationException.java b/group01/349209948/src/week2_0305/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..d80baae668 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ConfigurationException.java @@ -0,0 +1,18 @@ +package week2_0305.litestruts; +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/group01/349209948/src/week2_0305/litestruts/ConfigurationTest.java b/group01/349209948/src/week2_0305/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..3c2bf82ecc --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ConfigurationTest.java @@ -0,0 +1,51 @@ +package week2_0305.litestruts; + +import week2_0305.litestruts.Configuration; + +import org.junit.Assert; +import org.junit.Test; + +public class ConfigurationTest { + + Configuration cfg = new Configuration("struts.xml"); + + @Test + public void testGetClassName() { + String clzName = cfg.getClassName("login"); + Assert.assertEquals("week2_0305.litestruts.LoginAction", clzName); + clzName = cfg.getClassName("logout"); + Assert.assertEquals("week2_0305.litestruts.LogoutAction", clzName); + } + @Test + public void testGetFileName() { + String packageName = this.getClass().getPackage().getName(); + packageName = packageName.replace('.', '/'); + packageName = "/" + packageName + "/" + "struts.xml"; + Assert.assertEquals("/week2_0305/litestruts/struts.xml", packageName); + } + + @Test + public void testGetResultView() { + String actionName = "login"; + String resultName = "success"; + String viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/homepage.jsp", viewName); + + actionName = "login"; + resultName = "fail"; + viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/showLogin.jsp", viewName); + + actionName = "logout"; + resultName = "success"; + viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/welcome.jsp", viewName); + + actionName = "logout"; + resultName = "error"; + viewName = cfg.getResultView(actionName, resultName); + Assert.assertEquals("/jsp/error.jsp", viewName); + + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/LoginAction.java b/group01/349209948/src/week2_0305/litestruts/LoginAction.java new file mode 100644 index 0000000000..ed666b6645 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package week2_0305.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/group01/349209948/src/week2_0305/litestruts/ReflectionUtil.java b/group01/349209948/src/week2_0305/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..a670d6df04 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ReflectionUtil.java @@ -0,0 +1,74 @@ +package week2_0305.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; + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + List methods = new ArrayList<>(); + for (Method m : clz.getDeclaredMethods()) { + if (m.getName().startsWith("set")) { + methods.add(m); + } + } + return methods; + } + + public static List getGetterMethods(Class clz) { + List methods = new ArrayList(); + for (Method m : clz.getDeclaredMethods()) { + if (m.getName().startsWith("get")) { + methods.add(m); + } + } + return methods; + } + + public 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 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 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; + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/ReflectionUtilTest.java b/group01/349209948/src/week2_0305/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..242487da60 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/ReflectionUtilTest.java @@ -0,0 +1,130 @@ +package week2_0305.litestruts; + +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.Assert; +import org.junit.Test; + +public class ReflectionUtilTest { + + @Test + public void testGetSetterMethod() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectNames = new ArrayList<>(); + expectNames.add("setName"); + expectNames.add("setPassword"); + + Set actualNames = new HashSet<>(); + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + } + + @Test + public void testSetParameters() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap(); + params.put("name", "test"); + params.put("password", "123456"); + + 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("123456", f.get(o)); + } + + @Test + public void testGetGetterMethod() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + List expectNames = new ArrayList<>(); + expectNames.add("getName"); + expectNames.add("getPassword"); + expectNames.add("getMessage"); + + Set actualNames = new HashSet<>(); + + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + + } + + @Test + public void testGetMethods() throws Exception{ + String name = "week2_0305.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getMethods(clz, "get"); + + Assert.assertEquals(3, methods.size()); + List expectNames = new ArrayList<>(); + expectNames.add("getName"); + expectNames.add("getPassword"); + expectNames.add("getMessage"); + + Set actualNames = new HashSet<>(); + + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + + methods = ReflectionUtil.getMethods(clz, "set"); + + Assert.assertEquals(2, methods.size()); + + expectNames = new ArrayList<>(); + expectNames.add("setName"); + expectNames.add("setPassword"); + + actualNames = new HashSet<>(); + for(Method m : methods) { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectNames)); + } + + @Test + public void testGetParameters() throws Exception{ + String name = "week2_0305.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("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/Struts.java b/group01/349209948/src/week2_0305/litestruts/Struts.java new file mode 100644 index 0000000000..4b97a947c1 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/Struts.java @@ -0,0 +1,55 @@ +package week2_0305.litestruts; + +import java.lang.reflect.InvocationTargetException; +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); + + 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); + String jsp = cfg.getResultView(actionName, resultName); + Map params = ReflectionUtil.getParamterMap(action); + View view = new View(); + view.setJsp(jsp); + view.setParameters(params); + return view; + + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + +} diff --git a/group01/349209948/src/week2_0305/litestruts/StrutsTest.java b/group01/349209948/src/week2_0305/litestruts/StrutsTest.java new file mode 100644 index 0000000000..3b4ce1d7d1 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/StrutsTest.java @@ -0,0 +1,43 @@ +package week2_0305.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/group01/349209948/src/week2_0305/litestruts/View.java b/group01/349209948/src/week2_0305/litestruts/View.java new file mode 100644 index 0000000000..a414cad3e5 --- /dev/null +++ b/group01/349209948/src/week2_0305/litestruts/View.java @@ -0,0 +1,23 @@ +package week2_0305.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/group01/765324639/pom.xml b/group01/765324639/pom.xml new file mode 100644 index 0000000000..24816f0f3f --- /dev/null +++ b/group01/765324639/pom.xml @@ -0,0 +1,18 @@ + + 4.0.0 + com.zavier + 765324639Learning + 0.0.1-SNAPSHOT + + + junit + junit + 4.12 + + + dom4j + dom4j + 1.6.1 + + + \ No newline at end of file diff --git a/group01/765324639/src/zavier/week01/basic/BinaryTreeNode.java b/group01/765324639/src/main/java/datastructure/BinaryTreeNode.java similarity index 93% rename from group01/765324639/src/zavier/week01/basic/BinaryTreeNode.java rename to group01/765324639/src/main/java/datastructure/BinaryTreeNode.java index 6ef26e8f9a..20d0734f11 100644 --- a/group01/765324639/src/zavier/week01/basic/BinaryTreeNode.java +++ b/group01/765324639/src/main/java/datastructure/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package zavier.week01.basic; +package datastructure; public class BinaryTreeNode { diff --git a/group01/765324639/src/zavier/week01/basic/Iterator.java b/group01/765324639/src/main/java/datastructure/Iterator.java similarity index 70% rename from group01/765324639/src/zavier/week01/basic/Iterator.java rename to group01/765324639/src/main/java/datastructure/Iterator.java index 664983e0fd..ae54040424 100644 --- a/group01/765324639/src/zavier/week01/basic/Iterator.java +++ b/group01/765324639/src/main/java/datastructure/Iterator.java @@ -1,4 +1,4 @@ -package zavier.week01.basic; +package datastructure; public interface Iterator { public boolean hasNext(); diff --git a/group01/765324639/src/zavier/week01/basic/List.java b/group01/765324639/src/main/java/datastructure/List.java similarity index 82% rename from group01/765324639/src/zavier/week01/basic/List.java rename to group01/765324639/src/main/java/datastructure/List.java index 4f2d49bd73..507cca34a8 100644 --- a/group01/765324639/src/zavier/week01/basic/List.java +++ b/group01/765324639/src/main/java/datastructure/List.java @@ -1,4 +1,4 @@ -package zavier.week01.basic; +package datastructure; public interface List { public void add(Object o); diff --git a/group01/765324639/src/zavier/week01/basic/Queue.java b/group01/765324639/src/main/java/datastructure/Queue.java similarity index 81% rename from group01/765324639/src/zavier/week01/basic/Queue.java rename to group01/765324639/src/main/java/datastructure/Queue.java index 5a212d46c1..d4cfec525e 100644 --- a/group01/765324639/src/zavier/week01/basic/Queue.java +++ b/group01/765324639/src/main/java/datastructure/Queue.java @@ -1,4 +1,6 @@ -package zavier.week01.basic; +package datastructure; + +import datastructure.linkedlist.LinkedList; public class Queue { diff --git a/group01/765324639/src/zavier/week01/basic/ArrayList.java b/group01/765324639/src/main/java/datastructure/array/ArrayList.java similarity index 91% rename from group01/765324639/src/zavier/week01/basic/ArrayList.java rename to group01/765324639/src/main/java/datastructure/array/ArrayList.java index 38e5739fb8..a4b4182226 100644 --- a/group01/765324639/src/zavier/week01/basic/ArrayList.java +++ b/group01/765324639/src/main/java/datastructure/array/ArrayList.java @@ -1,7 +1,10 @@ -package zavier.week01.basic; +package datastructure.array; import java.util.Arrays; +import datastructure.Iterator; +import datastructure.List; + public class ArrayList implements List { private int size = 0; diff --git a/group01/765324639/src/zavier/week02/coderising/array/ArrayUtil.java b/group01/765324639/src/main/java/datastructure/array/ArrayUtil.java similarity index 95% rename from group01/765324639/src/zavier/week02/coderising/array/ArrayUtil.java rename to group01/765324639/src/main/java/datastructure/array/ArrayUtil.java index 96bff301c7..74040ccbe0 100644 --- a/group01/765324639/src/zavier/week02/coderising/array/ArrayUtil.java +++ b/group01/765324639/src/main/java/datastructure/array/ArrayUtil.java @@ -1,7 +1,6 @@ -package zavier.week02.coderising.array; +package datastructure.array; -import zavier.week01.basic.ArrayList; -import zavier.week01.basic.List; +import datastructure.List; public class ArrayUtil { diff --git a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java b/group01/765324639/src/main/java/datastructure/linkedlist/LRUPageFrame.java similarity index 94% rename from group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java rename to group01/765324639/src/main/java/datastructure/linkedlist/LRUPageFrame.java index eb82d94d5e..cc4771562d 100644 --- a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java +++ b/group01/765324639/src/main/java/datastructure/linkedlist/LRUPageFrame.java @@ -1,4 +1,4 @@ -package zavier.week04.coderising.linklist; +package datastructure.linkedlist; /** * 用双向链表实现LRU算法 diff --git a/group01/765324639/src/zavier/week01/basic/LinkedList.java b/group01/765324639/src/main/java/datastructure/linkedlist/LinkedList.java similarity index 95% rename from group01/765324639/src/zavier/week01/basic/LinkedList.java rename to group01/765324639/src/main/java/datastructure/linkedlist/LinkedList.java index 6e15220b34..acdb3320d9 100644 --- a/group01/765324639/src/zavier/week01/basic/LinkedList.java +++ b/group01/765324639/src/main/java/datastructure/linkedlist/LinkedList.java @@ -1,7 +1,10 @@ -package zavier.week01.basic; +package datastructure.linkedlist; import java.util.NoSuchElementException; +import datastructure.Iterator; +import datastructure.List; + public class LinkedList implements List { private Node head; diff --git a/group01/765324639/src/zavier/week01/basic/Stack.java b/group01/765324639/src/main/java/datastructure/stack/Stack.java similarity index 61% rename from group01/765324639/src/zavier/week01/basic/Stack.java rename to group01/765324639/src/main/java/datastructure/stack/Stack.java index ebe4afb19f..52d4f818e8 100644 --- a/group01/765324639/src/zavier/week01/basic/Stack.java +++ b/group01/765324639/src/main/java/datastructure/stack/Stack.java @@ -1,7 +1,9 @@ -package zavier.week01.basic; +package datastructure.stack; import java.util.EmptyStackException; +import datastructure.array.ArrayList; + public class Stack { private ArrayList elementData = new ArrayList(); @@ -30,4 +32,16 @@ public boolean isEmpty() { public int size() { return elementData.size(); } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + int i = 0; + for ( ; i < elementData.size() - 1; i++) { + builder.append(elementData.get(i) + ","); + } + builder.append(elementData.get(i)); + return builder.toString(); + } + } diff --git a/group01/765324639/src/main/java/datastructure/stack/StackUtil.java b/group01/765324639/src/main/java/datastructure/stack/StackUtil.java new file mode 100644 index 0000000000..b45f90337d --- /dev/null +++ b/group01/765324639/src/main/java/datastructure/stack/StackUtil.java @@ -0,0 +1,110 @@ +package datastructure.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + if (s == null || s.isEmpty()) { + return; + } + + Stack temp1 = new Stack(); + while (!s.isEmpty()) { + temp1.push(s.pop()); + } + Stack temp2 = new Stack(); + while (!temp1.isEmpty()) { + temp2.push(temp1.pop()); + } + while (!temp2.isEmpty()) { + s.push(temp2.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if (s == null || s.isEmpty()) { + return; + } + + Stack temp = new Stack(); + while (!s.isEmpty()) { + int num = (int) s.pop(); + if (num != (int)o) { + temp.push(num); + } + } + while (!temp.isEmpty()) { + s.push(temp.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (s == null || s.isEmpty() || len < 0) { + return null; + } + + Stack temp = new Stack(); + int i = 0; + Object[] obj = new Object[len]; + while(!s.isEmpty() && i < len) { + temp.push(s.peek()); + obj[i++] = s.pop(); + } + while (!temp.isEmpty()) { + s.push(temp.pop()); + } + return obj; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + if (s == null) { + return false; + } + + Stack stack = new Stack(); + char[] charArray = s.toCharArray(); + for (int i = 0; i < charArray.length; i++) { + char c = charArray[i]; + if (c == '(' || c == '[' || c == '{') { + stack.push(c); + } else if (c == ')') { + if ('(' != (char)stack.pop()) { + return false; + } + } else if (c == ']') { + if ('[' != (char)stack.pop()) { + return false; + } + } else if (c == '}') { + if ('{' != (char)stack.pop()) { + return false; + } + } + } + return true; + } + + +} diff --git a/group01/765324639/src/zavier/week03/coderising/download/DownloadThread.java b/group01/765324639/src/main/java/download/DownloadThread.java similarity index 84% rename from group01/765324639/src/zavier/week03/coderising/download/DownloadThread.java rename to group01/765324639/src/main/java/download/DownloadThread.java index f94c97b8b1..88641b3741 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/DownloadThread.java +++ b/group01/765324639/src/main/java/download/DownloadThread.java @@ -1,9 +1,9 @@ -package zavier.week03.coderising.download; +package download; import java.io.IOException; import java.io.RandomAccessFile; -import zavier.week03.coderising.download.api.Connection; +import download.api.Connection; public class DownloadThread extends Thread { @@ -22,6 +22,7 @@ public DownloadThread(Connection conn, int startPos, int endPos) { @Override public void run() { + System.out.println("start download:" + startPos + "~" + endPos); byte[] data = new byte[endPos - startPos]; try { data = conn.read(startPos, endPos); @@ -30,7 +31,7 @@ public void run() { } writeToFile(data); } - + private void writeToFile(byte[] data) { RandomAccessFile file; try { diff --git a/group01/765324639/src/zavier/week03/coderising/download/FileDownloader.java b/group01/765324639/src/main/java/download/FileDownloader.java similarity index 72% rename from group01/765324639/src/zavier/week03/coderising/download/FileDownloader.java rename to group01/765324639/src/main/java/download/FileDownloader.java index ff2db12f50..91f972db71 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/FileDownloader.java +++ b/group01/765324639/src/main/java/download/FileDownloader.java @@ -1,9 +1,12 @@ -package zavier.week03.coderising.download; +package download; -import zavier.week03.coderising.download.api.Connection; -import zavier.week03.coderising.download.api.ConnectionException; -import zavier.week03.coderising.download.api.ConnectionManager; -import zavier.week03.coderising.download.api.DownloadListener; +import java.io.IOException; +import java.io.RandomAccessFile; + +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; +import download.api.DownloadListener; public class FileDownloader { @@ -40,14 +43,15 @@ public void execute() { conn = cm.open(this.url); int length = conn.getContentLength(); + createPlaceHolderFile("download20170311.jpg", length); - DownloadThread downloadThread1 = new DownloadThread(conn, 0, length / 3); + DownloadThread downloadThread1 = new DownloadThread(cm.open(this.url), 0, length / 3); downloadThread1.start(); DownloadThread downloadThread2 = - new DownloadThread(conn, length / 3 + 1, length / 3 * 2); + new DownloadThread(cm.open(this.url), length / 3 + 1, length / 3 * 2); downloadThread2.start(); DownloadThread downloadThread3 = - new DownloadThread(conn, length / 3 * 2 + 1, length - 1); + new DownloadThread(cm.open(this.url), length / 3 * 2 + 1, length - 1); downloadThread3.start(); try { downloadThread1.join(); @@ -60,22 +64,31 @@ public void execute() { } catch (ConnectionException e) { e.printStackTrace(); + } catch (IOException e1) { + e1.printStackTrace(); } finally { if (conn != null) { conn.close(); } } + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + + RandomAccessFile file = new RandomAccessFile(fileName, "rw"); + for (int i = 0; i < contentLen; i++) { + file.write(0); + } + file.close(); } public void setListener(DownloadListener listener) { this.listener = listener; } - - public void setConnectionManager(ConnectionManager ucm) { this.cm = ucm; } diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/Connection.java b/group01/765324639/src/main/java/download/api/Connection.java similarity index 87% rename from group01/765324639/src/zavier/week03/coderising/download/api/Connection.java rename to group01/765324639/src/main/java/download/api/Connection.java index 4763202fab..c0c2a33285 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/api/Connection.java +++ b/group01/765324639/src/main/java/download/api/Connection.java @@ -1,4 +1,4 @@ -package zavier.week03.coderising.download.api; +package download.api; import java.io.IOException; diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionException.java b/group01/765324639/src/main/java/download/api/ConnectionException.java similarity index 52% rename from group01/765324639/src/zavier/week03/coderising/download/api/ConnectionException.java rename to group01/765324639/src/main/java/download/api/ConnectionException.java index 5df32804de..9daefa720f 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionException.java +++ b/group01/765324639/src/main/java/download/api/ConnectionException.java @@ -1,4 +1,4 @@ -package zavier.week03.coderising.download.api; +package download.api; public class ConnectionException extends Exception { diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionManager.java b/group01/765324639/src/main/java/download/api/ConnectionManager.java similarity index 78% rename from group01/765324639/src/zavier/week03/coderising/download/api/ConnectionManager.java rename to group01/765324639/src/main/java/download/api/ConnectionManager.java index 81f5f34f72..c74bf0d41f 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/api/ConnectionManager.java +++ b/group01/765324639/src/main/java/download/api/ConnectionManager.java @@ -1,4 +1,4 @@ -package zavier.week03.coderising.download.api; +package download.api; public interface ConnectionManager { /** diff --git a/group01/765324639/src/zavier/week03/coderising/download/api/DownloadListener.java b/group01/765324639/src/main/java/download/api/DownloadListener.java similarity index 58% rename from group01/765324639/src/zavier/week03/coderising/download/api/DownloadListener.java rename to group01/765324639/src/main/java/download/api/DownloadListener.java index f72ecd263d..f3730b32a1 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/api/DownloadListener.java +++ b/group01/765324639/src/main/java/download/api/DownloadListener.java @@ -1,4 +1,4 @@ -package zavier.week03.coderising.download.api; +package download.api; public interface DownloadListener { public void notifyFinished(); diff --git a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionImpl.java b/group01/765324639/src/main/java/download/impl/ConnectionImpl.java similarity index 88% rename from group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionImpl.java rename to group01/765324639/src/main/java/download/impl/ConnectionImpl.java index b297beef54..634fd6f1df 100644 --- a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionImpl.java +++ b/group01/765324639/src/main/java/download/impl/ConnectionImpl.java @@ -1,4 +1,4 @@ -package zavier.week03.coderising.download.impl; +package download.impl; import java.io.IOException; import java.io.InputStream; @@ -6,7 +6,7 @@ import java.net.MalformedURLException; import java.net.URL; -import zavier.week03.coderising.download.api.Connection; +import download.api.Connection; public class ConnectionImpl implements Connection { @@ -57,8 +57,6 @@ public int getContentLength() { @Override public void close() { - conn.disconnect(); - conn = null; } } diff --git a/group01/895457260/code/src/download/impl/ConnectionManagerImpl.java b/group01/765324639/src/main/java/download/impl/ConnectionManagerImpl.java similarity index 59% rename from group01/895457260/code/src/download/impl/ConnectionManagerImpl.java rename to group01/765324639/src/main/java/download/impl/ConnectionManagerImpl.java index be17fa9110..9663736f21 100644 --- a/group01/895457260/code/src/download/impl/ConnectionManagerImpl.java +++ b/group01/765324639/src/main/java/download/impl/ConnectionManagerImpl.java @@ -1,12 +1,14 @@ -package download.impl; - -import download.api.Connection; -import download.api.ConnectionException; -import download.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - @Override - public Connection open(String url) throws ConnectionException { - return new ConnectionImpl(url); - } -} +package download.impl; + +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group01/765324639/src/zavier/week02/coderising/litestruts/LoginAction.java b/group01/765324639/src/main/java/litestruts/LoginAction.java similarity index 90% rename from group01/765324639/src/zavier/week02/coderising/litestruts/LoginAction.java rename to group01/765324639/src/main/java/litestruts/LoginAction.java index 617b5f115b..87ae0c4fcf 100644 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/LoginAction.java +++ b/group01/765324639/src/main/java/litestruts/LoginAction.java @@ -1,4 +1,4 @@ -package zavier.week02.coderising.litestruts; +package litestruts; /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 diff --git a/group01/765324639/src/zavier/week02/coderising/litestruts/Struts.java b/group01/765324639/src/main/java/litestruts/Struts.java similarity index 96% rename from group01/765324639/src/zavier/week02/coderising/litestruts/Struts.java rename to group01/765324639/src/main/java/litestruts/Struts.java index d30beaafb3..5230e424e2 100644 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/Struts.java +++ b/group01/765324639/src/main/java/litestruts/Struts.java @@ -1,4 +1,4 @@ -package zavier.week02.coderising.litestruts; +package litestruts; import java.io.InputStream; import java.lang.reflect.Method; diff --git a/group01/765324639/src/zavier/week02/coderising/litestruts/View.java b/group01/765324639/src/main/java/litestruts/View.java similarity index 85% rename from group01/765324639/src/zavier/week02/coderising/litestruts/View.java rename to group01/765324639/src/main/java/litestruts/View.java index f164c4bfc5..4a553757d0 100644 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/View.java +++ b/group01/765324639/src/main/java/litestruts/View.java @@ -1,4 +1,4 @@ -package zavier.week02.coderising.litestruts; +package litestruts; import java.util.Map; diff --git a/group01/765324639/src/zavier/week02/coderising/litestruts/struts.xml b/group01/765324639/src/main/java/litestruts/struts.xml similarity index 63% rename from group01/765324639/src/zavier/week02/coderising/litestruts/struts.xml rename to group01/765324639/src/main/java/litestruts/struts.xml index ffe9110788..a7eccffd9c 100644 --- a/group01/765324639/src/zavier/week02/coderising/litestruts/struts.xml +++ b/group01/765324639/src/main/java/litestruts/struts.xml @@ -1,10 +1,10 @@ - + /jsp/homepage.jsp /jsp/showLogin.jsp - + /jsp/welcome.jsp /jsp/error.jsp diff --git a/group01/765324639/src/main/java/minijvm/clz/AccessFlag.java b/group01/765324639/src/main/java/minijvm/clz/AccessFlag.java new file mode 100644 index 0000000000..7585a3c460 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package minijvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/group01/765324639/src/main/java/minijvm/clz/ClassFile.java b/group01/765324639/src/main/java/minijvm/clz/ClassFile.java new file mode 100644 index 0000000000..36eddeb46d --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/clz/ClassFile.java @@ -0,0 +1,75 @@ +package minijvm.clz; + +import minijvm.constant.ClassInfo; +import minijvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/group01/765324639/src/main/java/minijvm/clz/ClassIndex.java b/group01/765324639/src/main/java/minijvm/clz/ClassIndex.java new file mode 100644 index 0000000000..4b25095924 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package minijvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/group01/765324639/src/main/java/minijvm/constant/ClassInfo.java b/group01/765324639/src/main/java/minijvm/constant/ClassInfo.java new file mode 100644 index 0000000000..c856052998 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/ClassInfo.java @@ -0,0 +1,25 @@ +package minijvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ; + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + @Override + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/ConstantInfo.java b/group01/765324639/src/main/java/minijvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..5fa0be0189 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package minijvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/ConstantPool.java b/group01/765324639/src/main/java/minijvm/constant/ConstantPool.java new file mode 100644 index 0000000000..12746a1f3c --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package minijvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/FieldRefInfo.java b/group01/765324639/src/main/java/minijvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..ddcf2df456 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/FieldRefInfo.java @@ -0,0 +1,56 @@ +package minijvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/MethodRefInfo.java b/group01/765324639/src/main/java/minijvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..f4c2368228 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/MethodRefInfo.java @@ -0,0 +1,57 @@ +package minijvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/NameAndTypeInfo.java b/group01/765324639/src/main/java/minijvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..de88422d82 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/NameAndTypeInfo.java @@ -0,0 +1,47 @@ +package minijvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + @Override + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + @Override + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/group01/765324639/src/main/java/minijvm/constant/NullConstantInfo.java b/group01/765324639/src/main/java/minijvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..88eb702f4b --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package minijvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/StringInfo.java b/group01/765324639/src/main/java/minijvm/constant/StringInfo.java new file mode 100644 index 0000000000..915652a93c --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/StringInfo.java @@ -0,0 +1,28 @@ +package minijvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + @Override + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/group01/765324639/src/main/java/minijvm/constant/UTF8Info.java b/group01/765324639/src/main/java/minijvm/constant/UTF8Info.java new file mode 100644 index 0000000000..1af71e8e9c --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/constant/UTF8Info.java @@ -0,0 +1,33 @@ +package minijvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + @Override + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/group01/765324639/src/main/java/minijvm/loader/ByteCodeIterator.java b/group01/765324639/src/main/java/minijvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..24a4db6f27 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/loader/ByteCodeIterator.java @@ -0,0 +1,47 @@ +package minijvm.loader; + +import java.io.UnsupportedEncodingException; + +import minijvm.util.Util; + +public class ByteCodeIterator { + + private byte[] codes; + + private int pos = 0; + + public ByteCodeIterator (byte[] codes) { + this.codes = codes; + } + + public int nextU1ToInt() { + return Util.byteToInt(new byte[]{codes[pos++]}); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[]{codes[pos++], codes[pos++]}); + } + + public String nextU4ToHexString() { + return Util.byteToHexString(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]}); + } + + public String nextLengthToString(int length) { + String dest = null; + try { + dest = new String(getBytes(length), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return dest; + } + + private byte[] getBytes(int length) { + byte[] b = new byte[length]; + for (int i = 0; i < length; i++) { + b[i] = codes[pos++]; + } + return b; + } + +} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java b/group01/765324639/src/main/java/minijvm/loader/ClassFileLoader.java similarity index 78% rename from group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java rename to group01/765324639/src/main/java/minijvm/loader/ClassFileLoader.java index 92a3fcfe02..51bce28f2a 100644 --- a/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java +++ b/group01/765324639/src/main/java/minijvm/loader/ClassFileLoader.java @@ -1,4 +1,4 @@ -package zavier.week04.coderising.jvm.loader; +package minijvm.loader; import java.io.ByteArrayOutputStream; import java.io.File; @@ -9,6 +9,8 @@ import java.util.ArrayList; import java.util.List; +import minijvm.clz.ClassFile; + public class ClassFileLoader { @@ -54,19 +56,25 @@ private byte[] readFileToByteArray(File classFile) { } private String convertClassNameToFilePath(String fillClassName) { - return fillClassName.replace(".", "\\") + ".class"; + return fillClassName.replace(".", File.separator) + ".class"; } public void addClassPath(String path) { + if (clzPaths.contains(path)) { + return; + } clzPaths.add(path); } - - public String getClassPath() { return String.join(";", clzPaths); } - + public ClassFile loadClass(String className) throws ClassNotFoundException { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } } diff --git a/group01/765324639/src/main/java/minijvm/loader/ClassFileParser.java b/group01/765324639/src/main/java/minijvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..dc800a211f --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/loader/ClassFileParser.java @@ -0,0 +1,119 @@ +package minijvm.loader; + +import minijvm.clz.AccessFlag; +import minijvm.clz.ClassFile; +import minijvm.clz.ClassIndex; +import minijvm.constant.ClassInfo; +import minijvm.constant.ConstantInfo; +import minijvm.constant.ConstantPool; +import minijvm.constant.FieldRefInfo; +import minijvm.constant.MethodRefInfo; +import minijvm.constant.NameAndTypeInfo; +import minijvm.constant.NullConstantInfo; +import minijvm.constant.StringInfo; +import minijvm.constant.UTF8Info; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ByteCodeIterator iter = new ByteCodeIterator(codes); + ClassFile classFile = new ClassFile(); + + String magicNumber = iter.nextU4ToHexString(); + if (!"cafebabe".equalsIgnoreCase(magicNumber)) { + return null; + } + + classFile.setMinorVersion(iter.nextU2ToInt()); + classFile.setMajorVersion(iter.nextU2ToInt()); + + ConstantPool pool = parseConstantPool(iter); + classFile.setConstPool(pool); + + classFile.setAccessFlag(parseAccessFlag(iter)); + classFile.setClassIndex(parseClassIndex(iter)); + + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + int flag = iter.nextU2ToInt(); + AccessFlag accessFlag = new AccessFlag(flag); + return accessFlag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + ClassIndex classIndex = new ClassIndex(); + int thisClassIndex = iter.nextU2ToInt(); + int superClassIndex = iter.nextU2ToInt(); + classIndex.setThisClassIndex(thisClassIndex); + classIndex.setSuperClassIndex(superClassIndex); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + int size = iter.nextU2ToInt(); + System.out.println("ConstantPool size: " + size); + + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); // 添加无效的第0项 + + for (int i = 1; i < size; i++) { + int tag = iter.nextU1ToInt(); + + if (tag == ConstantInfo.UTF8_INFO) { + UTF8Info utf8Info = new UTF8Info(pool); + int length = iter.nextU2ToInt(); + String value = iter.nextLengthToString(length); + utf8Info.setLength(length); + utf8Info.setValue(value); + + pool.addConstantInfo(utf8Info); + } else if (tag == ConstantInfo.CLASS_INFO) { + ClassInfo classInfo = new ClassInfo(pool); + int index = iter.nextU2ToInt(); + classInfo.setUtf8Index(index); + + pool.addConstantInfo(classInfo); + } else if (tag == ConstantInfo.STRING_INFO) { + StringInfo stringInfo = new StringInfo(pool); + int index = iter.nextU2ToInt(); + stringInfo.setIndex(index); + + pool.addConstantInfo(stringInfo); + } else if (tag == ConstantInfo.FIELD_INFO) { + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + int classInfoIndex = iter.nextU2ToInt(); + int nameAndTypeIndex = iter.nextU2ToInt(); + fieldRefInfo.setClassInfoIndex(classInfoIndex); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + pool.addConstantInfo(fieldRefInfo); + } else if (tag == ClassInfo.METHOD_INFO) { + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + int classInfoIndex = iter.nextU2ToInt(); + int nameAndTypeIndex = iter.nextU2ToInt(); + methodRefInfo.setClassInfoIndex(classInfoIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + + pool.addConstantInfo(methodRefInfo); + } else if (tag == ClassInfo.NAME_AND_TYPE_INFO) { + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + int index1 = iter.nextU2ToInt(); + int index2 = iter.nextU2ToInt(); + nameAndTypeInfo.setIndex1(index1); + nameAndTypeInfo.setIndex2(index2); + + pool.addConstantInfo(nameAndTypeInfo); + } else { + throw new RuntimeException("这个类型的常量还没有实现"); + } + + } + + return pool; + } + + +} diff --git a/group01/765324639/src/main/java/minijvm/util/Util.java b/group01/765324639/src/main/java/minijvm/util/Util.java new file mode 100644 index 0000000000..e6370a4997 --- /dev/null +++ b/group01/765324639/src/main/java/minijvm/util/Util.java @@ -0,0 +1,24 @@ +package minijvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + +} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java b/group01/765324639/src/test/java/minijvm/loader/EmployeeV1.java similarity index 87% rename from group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java rename to group01/765324639/src/test/java/minijvm/loader/EmployeeV1.java index 57c7517767..e501762cc4 100644 --- a/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java +++ b/group01/765324639/src/test/java/minijvm/loader/EmployeeV1.java @@ -1,8 +1,7 @@ -package zavier.week04.coderising.jvm.test; +package minijvm.loader; public class EmployeeV1 { - private String name; private int age; diff --git a/group01/765324639/src/zavier/week01/test/AllTests.java b/group01/765324639/src/zavier/week01/test/AllTests.java deleted file mode 100644 index c1755f6803..0000000000 --- a/group01/765324639/src/zavier/week01/test/AllTests.java +++ /dev/null @@ -1,12 +0,0 @@ -package zavier.week01.test; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ArrayListTest.class, LinkedListTest.class, QueueTest.class, StackTest.class, - BinaryTreeNodeTest.class}) -public class AllTests { - -} diff --git a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionManagerImpl.java b/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionManagerImpl.java deleted file mode 100644 index d6828e7ae8..0000000000 --- a/group01/765324639/src/zavier/week03/coderising/download/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,14 +0,0 @@ -package zavier.week03.coderising.download.impl; - -import zavier.week03.coderising.download.api.Connection; -import zavier.week03.coderising.download.api.ConnectionException; -import zavier.week03.coderising.download.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - - @Override - public Connection open(String url) throws ConnectionException { - return new ConnectionImpl(url); - } - -} diff --git a/group01/895457260/code/pom.xml b/group01/895457260/code/pom.xml new file mode 100644 index 0000000000..ab84ccfb98 --- /dev/null +++ b/group01/895457260/code/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + coderising + coding2017 + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + junit + junit + 4.12 + + + + + \ No newline at end of file diff --git a/group01/895457260/code/src/download/api/DownloadListener.java b/group01/895457260/code/src/download/api/DownloadListener.java deleted file mode 100644 index 0acf8ea483..0000000000 --- a/group01/895457260/code/src/download/api/DownloadListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package download.api; - -public interface DownloadListener { - /** - * 下载成功后自动调用此方法 - */ - void notifyFinished(); -} diff --git a/group01/895457260/code/src/download/impl/ConnectionImpl.java b/group01/895457260/code/src/download/impl/ConnectionImpl.java deleted file mode 100644 index 74e431a324..0000000000 --- a/group01/895457260/code/src/download/impl/ConnectionImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -package download.impl; - -import java.io.*; -import java.net.URL; -import java.net.URLConnection; - -import download.api.Connection; -import download.api.ConnectionException; - -public class ConnectionImpl implements Connection { - private URLConnection connection; - private InputStream inputStream; - - ConnectionImpl(String url) throws ConnectionException { - try { - init(url); - } catch (IOException e) { - throw new ConnectionException(); - } - } - - private void init(String url) throws IOException { - connection = new URL(url).openConnection(); - inputStream = new BufferedInputStream(connection.getInputStream()); - inputStream.mark(connection.getContentLength()); // 标记在开头 - } - - @Override - public byte[] read(int startPos, int endPos) throws IOException { - inputStream.reset(); // reset回到标记处 - skipBytes(startPos); - byte[] bytes = new byte[endPos - startPos]; - int n = inputStream.read(bytes); - return n == -1 ? new byte[0] : bytes; - } - - @Override - public int getContentLength() { - return connection.getContentLength(); - } - - @Override - public void close() { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - // InputStream.skip(long)实际跳过的字节数经常小于参数值,但不会大于参数值 - private void skipBytes(long n) throws IOException { - while (n > 0) { - n -= inputStream.skip(n); - } - } -} diff --git a/group01/895457260/code/src/algorithm/ArrayUtil.java b/group01/895457260/code/src/main/java/algorithm/ArrayUtil.java similarity index 100% rename from group01/895457260/code/src/algorithm/ArrayUtil.java rename to group01/895457260/code/src/main/java/algorithm/ArrayUtil.java diff --git a/group01/895457260/code/src/main/java/algorithm/lru/LRUPageFrame.java b/group01/895457260/code/src/main/java/algorithm/lru/LRUPageFrame.java new file mode 100644 index 0000000000..96e28c9ba7 --- /dev/null +++ b/group01/895457260/code/src/main/java/algorithm/lru/LRUPageFrame.java @@ -0,0 +1,112 @@ +package algorithm.lru; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + private static class List { + int capacity; + int size; + Node head;// 链表头 + Node rear;// 链表尾 + static class Node { + Node pre; + Node next; + int pageNum; + Node() {} + void clear() { + pre = null; + next = null; + } + } + List(int capacity) { + this.capacity = capacity; + head = new Node(); + rear = new Node(); + head.next = rear; + rear.pre = head; + } + void put(int pageNum) { + Node node = findNode(pageNum); + if (node == null) { + if (size >= capacity) { + remove(); + } + Node n = new Node(); + n.pageNum = pageNum; + n.next = rear; + n.pre = rear.pre; + n.pre.next = n; + rear.pre = n; + size++; + } else { + pullUp(node); + } + } + Node findNode(int pageNum) { + for (Node n = head.next; n != null && n != rear; n = n.next) { + if (n.pageNum == pageNum) { + return n; + } + } + return null; + } + void remove() { + if (size == 0) { + return; + } + List.Node node = head.next; + node.next.pre = head; + head.next = node.next; + node.clear(); + size--; + } + void pullUp(Node node) { + node.next.pre = node.pre; + node.pre.next = node.next; + node.next = rear; + node.pre = rear.pre; + rear.pre.next = node; + rear.pre = node; + } + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = rear.pre; + while(node != null && node != head){ + buffer.append(node.pageNum); + + node = node.pre; + if(node != null){ + buffer.append(","); + } + } + return buffer.length() == 0 ? "" : buffer.substring(0, buffer.length() - 1); + } + } + + private List buf; + private int capacity; + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + buf = new List(capacity); + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + buf.put(pageNum); + } + + @Override + public String toString() { + return buf.toString(); + } +} diff --git a/group01/895457260/code/src/datastructure/basic/ArrayList.java b/group01/895457260/code/src/main/java/datastructure/basic/ArrayList.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/ArrayList.java rename to group01/895457260/code/src/main/java/datastructure/basic/ArrayList.java diff --git a/group01/895457260/code/src/datastructure/basic/BinarySortedTree.java b/group01/895457260/code/src/main/java/datastructure/basic/BinarySortedTree.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/BinarySortedTree.java rename to group01/895457260/code/src/main/java/datastructure/basic/BinarySortedTree.java diff --git a/group01/895457260/code/src/datastructure/basic/BinaryTreeNode.java b/group01/895457260/code/src/main/java/datastructure/basic/BinaryTreeNode.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/BinaryTreeNode.java rename to group01/895457260/code/src/main/java/datastructure/basic/BinaryTreeNode.java diff --git a/group01/895457260/code/src/datastructure/basic/Iterator.java b/group01/895457260/code/src/main/java/datastructure/basic/Iterator.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/Iterator.java rename to group01/895457260/code/src/main/java/datastructure/basic/Iterator.java diff --git a/group01/895457260/code/src/datastructure/basic/LinkedList.java b/group01/895457260/code/src/main/java/datastructure/basic/LinkedList.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/LinkedList.java rename to group01/895457260/code/src/main/java/datastructure/basic/LinkedList.java diff --git a/group01/895457260/code/src/datastructure/basic/List.java b/group01/895457260/code/src/main/java/datastructure/basic/List.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/List.java rename to group01/895457260/code/src/main/java/datastructure/basic/List.java diff --git a/group01/895457260/code/src/datastructure/basic/Queue.java b/group01/895457260/code/src/main/java/datastructure/basic/Queue.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/Queue.java rename to group01/895457260/code/src/main/java/datastructure/basic/Queue.java diff --git a/group01/895457260/code/src/datastructure/basic/Stack.java b/group01/895457260/code/src/main/java/datastructure/basic/Stack.java similarity index 100% rename from group01/895457260/code/src/datastructure/basic/Stack.java rename to group01/895457260/code/src/main/java/datastructure/basic/Stack.java diff --git a/group01/895457260/code/src/datastructure/exception/EmptyListException.java b/group01/895457260/code/src/main/java/datastructure/exception/EmptyListException.java similarity index 100% rename from group01/895457260/code/src/datastructure/exception/EmptyListException.java rename to group01/895457260/code/src/main/java/datastructure/exception/EmptyListException.java diff --git a/group01/895457260/code/src/datastructure/exception/EmptyQueueException.java b/group01/895457260/code/src/main/java/datastructure/exception/EmptyQueueException.java similarity index 100% rename from group01/895457260/code/src/datastructure/exception/EmptyQueueException.java rename to group01/895457260/code/src/main/java/datastructure/exception/EmptyQueueException.java diff --git a/group01/895457260/code/src/download/Config.java b/group01/895457260/code/src/main/java/download/Config.java similarity index 59% rename from group01/895457260/code/src/download/Config.java rename to group01/895457260/code/src/main/java/download/Config.java index a104355cef..1a2abee421 100644 --- a/group01/895457260/code/src/download/Config.java +++ b/group01/895457260/code/src/main/java/download/Config.java @@ -7,9 +7,15 @@ * */ public class Config { + public static final String packageName = "download"; + /** * 保存下载文件的目录 */ public static File targetDirectory = new File("download/"); public static File tempDirectory = new File(targetDirectory, "temp/"); + + public static int maxLengthPerThread = 10 * 1024 * 1024; + public static int minThreadCount = 3; + public static int maxThreadCount = 8; } diff --git a/group01/895457260/code/src/download/DownloadThread.java b/group01/895457260/code/src/main/java/download/DownloadThread.java similarity index 59% rename from group01/895457260/code/src/download/DownloadThread.java rename to group01/895457260/code/src/main/java/download/DownloadThread.java index 97b9d66a51..fe619d8775 100644 --- a/group01/895457260/code/src/download/DownloadThread.java +++ b/group01/895457260/code/src/main/java/download/DownloadThread.java @@ -1,7 +1,6 @@ package download; -import download.api.Connection; -import download.api.DownloadException; +import download.api.*; import java.io.File; import java.io.FileNotFoundException; @@ -10,18 +9,11 @@ public class DownloadThread extends Thread { private Connection conn; - private int startPos; - private int endPos; - private File targetFile; - private OnCompleteListener onComplete; - private OnFailListener onFail; + private DownloadCallback callback = new DownloadCallback(); /** - * * @param conn url连接 - * @param startPos 此线程会从url所指向文件的startPos处开始下载 - * @param endPos 此线程会在url所指向文件的endPos处停止下载 * @param targetFile 保存下载内容的文件 * @param onComplete 下载成功后自动调用 * @param onFail 下载失败后自动调用 @@ -29,14 +21,12 @@ public class DownloadThread extends Thread { * @see OnCompleteListener#onComplete() * @see OnFailListener#onFail() */ - DownloadThread(Connection conn, int startPos, int endPos, File targetFile, + DownloadThread(Connection conn, File targetFile, OnCompleteListener onComplete, OnFailListener onFail) { - this.conn = conn; - this.startPos = startPos; - this.endPos = endPos; + this.conn = conn; this.targetFile = targetFile; - this.onComplete = onComplete; - this.onFail = onFail; + callback.setOnComplete(onComplete); + callback.setOnFail(onFail); } @Override @@ -56,19 +46,7 @@ public void run() { } } } - callback(success); - } - - private void callback(boolean success) { - if (success) { - if (onComplete != null) { - onComplete.onComplete(); - } - } else { - if (onFail != null) { - onFail.onFail(); - } - } + callback.callback(success); } private boolean tryDownload() throws DownloadException { @@ -97,8 +75,9 @@ private boolean tryDownload() throws DownloadException { private void retry() { try { recreateFile(targetFile); - } catch (IOException e1) { - e1.printStackTrace(); + conn.reset(); + } catch (IOException e) { + e.printStackTrace(); } } @@ -109,27 +88,11 @@ private void recreateFile(File file) throws IOException { private void download(FileOutputStream fos) throws IOException { int bufSize = 1024; - int from = startPos; - while (from < endPos) { - int to = Math.min(from + bufSize, endPos); - byte[] buf = conn.read(from, to); - from = to; - fos.write(buf); + byte[] buf = new byte[bufSize]; + int len; + while ((len = conn.read(buf)) != -1) { + fos.write(buf, 0, len); fos.flush(); } } - - public interface OnCompleteListener { - /** - * 下载成功后自动调用此方法 - */ - void onComplete(); - } - - public interface OnFailListener { - /** - * 下载失败后自动调用此方法 - */ - void onFail(); - } } diff --git a/group01/895457260/code/src/download/FileDownloader.java b/group01/895457260/code/src/main/java/download/FileDownloader.java similarity index 69% rename from group01/895457260/code/src/download/FileDownloader.java rename to group01/895457260/code/src/main/java/download/FileDownloader.java index f72d371788..a1d4197781 100644 --- a/group01/895457260/code/src/download/FileDownloader.java +++ b/group01/895457260/code/src/main/java/download/FileDownloader.java @@ -3,17 +3,20 @@ import download.api.*; import java.io.*; +import java.net.URL; import java.util.Date; /** * TODO: */ public class FileDownloader { - private String url; - private DownloadListener listener; + private String url = null; + private int contentLength; private ConnectionManager manager; private boolean failed = false; + private DownloadCallback callback = new DownloadCallback(); + private final int[] completedThreadCount = new int[1]; /** @@ -22,13 +25,16 @@ public class FileDownloader { * @see Config#targetDirectory * @see #execute() */ - public FileDownloader(String url) { + public FileDownloader(String url) throws IOException { this.url = url; + this.contentLength = new URL(url).openConnection().getContentLength(); } /** - * 开始下载 - * 调用这个方法前,先调用{@link #setConnectionManager(ConnectionManager)}和{@link #setListener(DownloadListener)} + * 开始下载
+ * 调用这个方法前,先调用以下几个方法:
{@link #setConnectionManager(ConnectionManager)}
+ * {@link #setOnCompleteListener(OnCompleteListener)}
+ * {@link #setOnFailListener(OnFailListener)} */ public void execute() { // 在这里实现你的代码, 注意: 需要用多线程实现下载 @@ -47,7 +53,14 @@ public void execute() { new Thread(() -> { initDirectories(); - int threadCount = 4; + int threadCount; + try { + threadCount = getThreadCount(); + } catch (IOException e) { + e.printStackTrace(); + callback.callback(false); + return; + } File[] tempFiles = new File[threadCount]; Connection[] connections = new Connection[threadCount]; createMultiThread(threadCount, tempFiles, connections); @@ -61,12 +74,27 @@ public void execute() { c.close(); } } - if (!failed && listener != null) { - listener.notifyFinished(); - } + callback.callback(true); }).start(); } + private int getThreadCount() throws IOException { + if (this.url.split(":", 2)[0].toLowerCase().startsWith("http")) { + URL url = new URL(this.url); + int length = url.openConnection().getContentLength(); + int count = length / Config.maxLengthPerThread; + if (count < Config.minThreadCount) { + return Config.minThreadCount; + } else if (count > Config.maxThreadCount) { + return Config.maxThreadCount; + } else { + return count; + } + } else { + return 1; + } + } + private void removeTempFiles(File[] tempFiles) { for (File tempFile : tempFiles) { tempFile.delete(); // 只删除临时文件,不删除临时目录 @@ -115,13 +143,13 @@ private void createMultiThread(int threadCount, File[] tempFiles, Connection[] c new Date().getTime() + "_" + i); tempFiles[i] = targetFile; - Connection connection = connect(); + int startPos = (int) (1.0 * contentLength / threadCount * i); + int endPos = i == threadCount - 1 ? contentLength : (int) (1.0 * contentLength / threadCount * (i + 1)); + endPos--; + Connection connection = connect(startPos, endPos); if (connection != null) { connections[i] = connection; - int length = connection.getContentLength(); - int startPos = (int) (1.0 * length / threadCount * i); - int endPos = i == threadCount - 1 ? length : (int) (1.0 * length / threadCount * (i + 1)); - new DownloadThread(connection, startPos, endPos, targetFile, () -> { + new DownloadThread(connection, targetFile, () -> { synchronized (completedThreadCount) { completedThreadCount[0]++; completedThreadCount.notifyAll(); @@ -137,14 +165,13 @@ private void createMultiThread(int threadCount, File[] tempFiles, Connection[] c } } - private Connection connect() { - Connection conn = null; + private Connection connect(int startPos, int endPos) { try { - conn = manager.open(this.url); + return manager.open(url, startPos, endPos); } catch (ConnectionException e) { e.printStackTrace(); + return null; } - return conn; } private void initDirectories() { @@ -191,17 +218,26 @@ private void write(File inputFile, OutputStream os) { /** * - * @param listener 下载成功后会调用listener.notifyFinished(),失败则不会调用 - * @see DownloadListener#notifyFinished() + * @param listener 下载成功后会调用onComplete.onComplete(),失败则不会调用 + * @see OnCompleteListener#onComplete() + */ + public void setOnCompleteListener(OnCompleteListener listener) { + callback.setOnComplete(listener); + } + + /** + * + * @param listener 下载失败后会调用onFail.onFail() + * @see OnFailListener#onFail() */ - public void setListener(DownloadListener listener) { - this.listener = listener; + public void setOnFailListener(OnFailListener listener) { + callback.setOnFail(listener); } /** * * @param manager 通过url打开连接 - * @see ConnectionManager#open(String) + * @see ConnectionManager#open(String, int, int) */ public void setConnectionManager(ConnectionManager manager) { this.manager = manager; diff --git a/group01/895457260/code/src/main/java/download/api/Connection.java b/group01/895457260/code/src/main/java/download/api/Connection.java new file mode 100644 index 0000000000..4b58ae145d --- /dev/null +++ b/group01/895457260/code/src/main/java/download/api/Connection.java @@ -0,0 +1,27 @@ +package download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 读取字节 + * @param bytes 存放读出的字节 + * @return 实际读出的字节数 + */ + int read(byte[] bytes) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + int getContentLength(); + + /** + * 恢复到初始状态,可以重新读字节 + */ + void reset() throws IOException; + + /** + * 关闭连接 + */ + void close(); +} diff --git a/group01/895457260/code/src/download/api/ConnectionException.java b/group01/895457260/code/src/main/java/download/api/ConnectionException.java similarity index 100% rename from group01/895457260/code/src/download/api/ConnectionException.java rename to group01/895457260/code/src/main/java/download/api/ConnectionException.java diff --git a/group01/895457260/code/src/main/java/download/api/ConnectionManager.java b/group01/895457260/code/src/main/java/download/api/ConnectionManager.java new file mode 100644 index 0000000000..b88cf3b448 --- /dev/null +++ b/group01/895457260/code/src/main/java/download/api/ConnectionManager.java @@ -0,0 +1,13 @@ +package download.api; + +public interface ConnectionManager { + /** + * 打开一个连接 + * @param url url + * @param startPos 开始位置 + * @param endPos 结束位置 + * @return 打开的连接 + * @throws ConnectionException 参数错误 + */ + Connection open(String url, int startPos, int endPos) throws ConnectionException; +} diff --git a/group01/895457260/code/src/main/java/download/api/DownloadCallback.java b/group01/895457260/code/src/main/java/download/api/DownloadCallback.java new file mode 100644 index 0000000000..13b3bd781f --- /dev/null +++ b/group01/895457260/code/src/main/java/download/api/DownloadCallback.java @@ -0,0 +1,30 @@ +package download.api; + +/** + * Created by Haochen on 2017/3/16. + * TODO: + */ +public class DownloadCallback { + private OnCompleteListener onComplete; + private OnFailListener onFail; + + public void callback(boolean success) { + if (success) { + if (onComplete != null) { + onComplete.onComplete(); + } + } else { + if (onFail != null) { + onFail.onFail(); + } + } + } + + public void setOnComplete(OnCompleteListener onComplete) { + this.onComplete = onComplete; + } + + public void setOnFail(OnFailListener onFail) { + this.onFail = onFail; + } +} diff --git a/group01/895457260/code/src/download/api/DownloadException.java b/group01/895457260/code/src/main/java/download/api/DownloadException.java similarity index 100% rename from group01/895457260/code/src/download/api/DownloadException.java rename to group01/895457260/code/src/main/java/download/api/DownloadException.java diff --git a/group01/895457260/code/src/main/java/download/api/OnCompleteListener.java b/group01/895457260/code/src/main/java/download/api/OnCompleteListener.java new file mode 100644 index 0000000000..f2ce5ea4e8 --- /dev/null +++ b/group01/895457260/code/src/main/java/download/api/OnCompleteListener.java @@ -0,0 +1,12 @@ +package download.api; + +/** + * Created by Haochen on 2017/3/16. + * TODO: + */ +public interface OnCompleteListener { + /** + * 下载成功后自动调用此方法 + */ + void onComplete(); +} diff --git a/group01/895457260/code/src/main/java/download/api/OnFailListener.java b/group01/895457260/code/src/main/java/download/api/OnFailListener.java new file mode 100644 index 0000000000..7e79e6cb8a --- /dev/null +++ b/group01/895457260/code/src/main/java/download/api/OnFailListener.java @@ -0,0 +1,12 @@ +package download.api; + +/** + * Created by Haochen on 2017/3/16. + * TODO: + */ +public interface OnFailListener { + /** + * 下载失败后自动调用此方法 + */ + void onFail(); +} diff --git a/group01/895457260/code/src/main/java/download/impl/BaseConnection.java b/group01/895457260/code/src/main/java/download/impl/BaseConnection.java new file mode 100644 index 0000000000..72a2651e6e --- /dev/null +++ b/group01/895457260/code/src/main/java/download/impl/BaseConnection.java @@ -0,0 +1,76 @@ +package download.impl; + +import download.api.Connection; +import download.api.ConnectionException; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +/** + * Created by Haochen on 2017/3/16. + * TODO: + */ +public abstract class BaseConnection implements Connection { + URLConnection connection; + InputStream inputStream; + + private int contentLength; + private int readLen; + + BaseConnection(String url, int startPos, int endPos) throws ConnectionException { + contentLength = endPos - startPos + 1; + try { + connection = new URL(url).openConnection(); + init(startPos, endPos); + inputStream.mark(contentLength); + } catch (IOException e) { + throw new ConnectionException(); + } + } + + @Override + public int read(byte[] buf) throws IOException { + if (readLen >= contentLength) { + return -1; + } + int n = inputStream.read(buf); + if (readLen + n >= contentLength) { + n = contentLength - readLen; + readLen = contentLength; + } else { + readLen += n; + } + return n; + } + + protected abstract void init(int startPos, int endPos) throws IOException; + + @Override + public int getContentLength() { + return connection.getContentLength(); + } + + @Override + public void reset() throws IOException { + inputStream.reset(); + readLen = 0; + } + + @Override + public void close() { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + void openInputStream() throws IOException { + inputStream = new BufferedInputStream(connection.getInputStream()); + } +} diff --git a/group01/895457260/code/src/main/java/download/impl/ConnectionManagerImpl.java b/group01/895457260/code/src/main/java/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..116b6137b9 --- /dev/null +++ b/group01/895457260/code/src/main/java/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,29 @@ +package download.impl; + +import download.Config; +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; + +import java.lang.reflect.InvocationTargetException; + +public class ConnectionManagerImpl implements ConnectionManager { + @Override + public Connection open(String url, int startPos, int endPos) throws ConnectionException { + String protocol = url.split(":", 2)[0]; + try { + Class clazz = Class.forName(getClassName(protocol)); + return (Connection) clazz.getDeclaredConstructor(String.class, int.class, int.class) + .newInstance(url, startPos, endPos); + } catch (ClassNotFoundException | IllegalAccessException | + NoSuchMethodException | InstantiationException | InvocationTargetException e) { + return new DefaultConnection(url, startPos, endPos); + } + } + + private String getClassName(String protocol) { + String packageName = Config.packageName + ".impl."; + String className = Character.toUpperCase(protocol.charAt(0)) + protocol.substring(1) + "Connection"; + return packageName + className; + } +} diff --git a/group01/895457260/code/src/main/java/download/impl/DefaultConnection.java b/group01/895457260/code/src/main/java/download/impl/DefaultConnection.java new file mode 100644 index 0000000000..54139b2e94 --- /dev/null +++ b/group01/895457260/code/src/main/java/download/impl/DefaultConnection.java @@ -0,0 +1,28 @@ +package download.impl; + +import download.api.ConnectionException; + +import java.io.IOException; + +/** + * Created by Haochen on 2017/3/16. + * TODO: + */ +class DefaultConnection extends BaseConnection { + + DefaultConnection(String url, int startPos, int endPos) throws ConnectionException { + super(url, startPos, endPos); + } + + @Override + protected void init(int startPos, int endPos) throws IOException { + openInputStream(); + skipBytes(startPos); + } + + private void skipBytes(long n) throws IOException { + while (n > 0) { + n -= inputStream.skip(n); + } + } +} diff --git a/group01/895457260/code/src/main/java/download/impl/HttpConnection.java b/group01/895457260/code/src/main/java/download/impl/HttpConnection.java new file mode 100644 index 0000000000..04fbcc9dea --- /dev/null +++ b/group01/895457260/code/src/main/java/download/impl/HttpConnection.java @@ -0,0 +1,20 @@ +package download.impl; + +import java.io.*; +import java.net.HttpURLConnection; + +import download.api.ConnectionException; + +class HttpConnection extends BaseConnection { + + HttpConnection(String url, int startPos, int endPos) throws ConnectionException { + super(url, startPos, endPos); + } + + @Override + protected void init(int startPos, int endPos) throws IOException { + HttpURLConnection connection = (HttpURLConnection) super.connection; + connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + openInputStream(); + } +} diff --git a/group01/895457260/code/src/main/java/download/impl/HttpsConnection.java b/group01/895457260/code/src/main/java/download/impl/HttpsConnection.java new file mode 100644 index 0000000000..0179044719 --- /dev/null +++ b/group01/895457260/code/src/main/java/download/impl/HttpsConnection.java @@ -0,0 +1,24 @@ +package download.impl; + +import download.api.ConnectionException; + +import javax.net.ssl.HttpsURLConnection; +import java.io.IOException; + +/** + * Created by Haochen on 2017/3/16. + * TODO: + */ +public class HttpsConnection extends BaseConnection { + + HttpsConnection(String url, int startPos, int endPos) throws ConnectionException { + super(url, startPos, endPos); + } + + @Override + protected void init(int startPos, int endPos) throws IOException { + HttpsURLConnection connection = (HttpsURLConnection) super.connection; + connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + openInputStream(); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java b/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java new file mode 100644 index 0000000000..53e401c119 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/ClassFileLoader.java @@ -0,0 +1,80 @@ +package jvm; + +import jvm.exception.ClassDuplicateException; +import jvm.exception.ClassNotExistsException; +import jvm.exception.ReadClassException; +import jvm.util.ArrayUtils; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ClassFileLoader { + + private List classPaths = new ArrayList<>(); + + public byte[] readBinaryCode(String className) throws ReadClassException { + File file = getClassFile(className); + if (file == null) { + throw new ClassNotExistsException(); + } + InputStream is; + try { + is = new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new ClassNotExistsException(); + } + List bytes = new ArrayList<>(); + byte[] buf = new byte[1024]; + int len; + try { + while ((len = is.read(buf)) != -1) { + bytes.addAll(ArrayUtils.toList(buf, 0, len)); + } + } catch (IOException e) { + e.printStackTrace(); + } + return ArrayUtils.toArray(bytes); + } + + private File getClassFile(String className) throws ClassDuplicateException { + int split = className.lastIndexOf('.'); + String fileName = className.substring(split + 1) + ".class"; + String subPath = className.substring(0, split).replaceAll("[.]", "/"); + List files = new ArrayList<>(); + for (String path : classPaths) { + File dir = new File(path + '/' + subPath); + File[] listFile = dir.listFiles((dir1, name) -> name.equals(fileName)); + if (listFile != null) { + Arrays.stream(listFile).forEach(files::add); + } + } + if (files.size() > 1) { + throw new ClassDuplicateException(); + } + return files.size() == 1 ? files.get(0) : null; + } + + public void addClassPath(String path) { + if (path != null && !"".equals(path)) { + classPaths.add(path); + } + } + + public String getClassPath() { + StringBuilder builder = new StringBuilder(); + classPaths.forEach((i) -> builder.append(';').append(i)); + return builder.substring(1); + } + + boolean checkMagicNumber(byte[] bytes) { + String magicNumber = "CAFEBABE"; + String str = ""; + int byteNum = 4; + for (int i = 0; i < byteNum; ++i) { + str += Integer.toHexString(Byte.toUnsignedInt(bytes[i])); + } + return magicNumber.equals(str.toUpperCase()); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/LiteJvm.java b/group01/895457260/code/src/main/java/jvm/LiteJvm.java new file mode 100644 index 0000000000..d642654d5f --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/LiteJvm.java @@ -0,0 +1,25 @@ +package jvm; + +import jvm.exception.MagicNumberException; +import jvm.exception.ReadClassException; + +/** + * Created by Haochen on 2017/3/26. + * TODO: + */ +public enum LiteJvm { + INSTANCE; + + private ClassFileLoader classFileLoader = new ClassFileLoader(); + + public void launch(String className) throws MagicNumberException, ReadClassException { + byte[] bytes = getBytes(className); + if (!classFileLoader.checkMagicNumber(bytes)) { + throw new MagicNumberException(); + } + } + + private byte[] getBytes(String className) throws ReadClassException { + return classFileLoader.readBinaryCode(className); + } +} diff --git a/group01/895457260/code/src/main/java/jvm/exception/ClassDuplicateException.java b/group01/895457260/code/src/main/java/jvm/exception/ClassDuplicateException.java new file mode 100644 index 0000000000..8666fb9177 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/exception/ClassDuplicateException.java @@ -0,0 +1,7 @@ +package jvm.exception; + +/** + * Created by Haochen on 2017/3/27. + * TODO: + */ +public class ClassDuplicateException extends ReadClassException {} diff --git a/group01/895457260/code/src/main/java/jvm/exception/ClassNotExistsException.java b/group01/895457260/code/src/main/java/jvm/exception/ClassNotExistsException.java new file mode 100644 index 0000000000..053fd19076 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/exception/ClassNotExistsException.java @@ -0,0 +1,7 @@ +package jvm.exception; + +/** + * Created by Haochen on 2017/3/27. + * TODO: + */ +public class ClassNotExistsException extends ReadClassException {} diff --git a/group01/895457260/code/src/main/java/jvm/exception/MagicNumberException.java b/group01/895457260/code/src/main/java/jvm/exception/MagicNumberException.java new file mode 100644 index 0000000000..712ea4f540 --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/exception/MagicNumberException.java @@ -0,0 +1,7 @@ +package jvm.exception; + +/** + * Created by Haochen on 2017/3/26. + * TODO: + */ +public class MagicNumberException extends Exception {} diff --git a/group01/895457260/code/src/main/java/jvm/exception/ReadClassException.java b/group01/895457260/code/src/main/java/jvm/exception/ReadClassException.java new file mode 100644 index 0000000000..490405a24f --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/exception/ReadClassException.java @@ -0,0 +1,7 @@ +package jvm.exception; + +/** + * Created by Haochen on 2017/3/27. + * TODO: + */ +public class ReadClassException extends Exception {} diff --git a/group01/895457260/code/src/main/java/jvm/util/ArrayUtils.java b/group01/895457260/code/src/main/java/jvm/util/ArrayUtils.java new file mode 100644 index 0000000000..7cc915a98d --- /dev/null +++ b/group01/895457260/code/src/main/java/jvm/util/ArrayUtils.java @@ -0,0 +1,31 @@ +package jvm.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Created by Haochen on 2017/3/26. + * TODO: + */ +public class ArrayUtils { + public static Collection toList(byte[] array, int start, int length){ + Collection list = new ArrayList<>(); + byte[] newArray = new byte[length]; + System.arraycopy(array, start, newArray, 0, length); + for (byte b : newArray) { + list.add(b); + } + return list; + } + + public static byte[] toArray(Collection c) { + byte[] bytes = new byte[c.size()]; + int pos = 0; + for (byte b : c) { + bytes[pos++] = b; + } + return bytes; + } +} diff --git a/group01/895457260/code/src/litestruts/Struts.java b/group01/895457260/code/src/main/java/litestruts/Struts.java similarity index 100% rename from group01/895457260/code/src/litestruts/Struts.java rename to group01/895457260/code/src/main/java/litestruts/Struts.java diff --git a/group01/895457260/code/src/litestruts/View.java b/group01/895457260/code/src/main/java/litestruts/View.java similarity index 100% rename from group01/895457260/code/src/litestruts/View.java rename to group01/895457260/code/src/main/java/litestruts/View.java diff --git a/group01/895457260/code/src/litestruts/action/LoginAction.java b/group01/895457260/code/src/main/java/litestruts/action/LoginAction.java similarity index 100% rename from group01/895457260/code/src/litestruts/action/LoginAction.java rename to group01/895457260/code/src/main/java/litestruts/action/LoginAction.java diff --git a/group01/895457260/code/src/litestruts/exception/XmlElementNotFoundException.java b/group01/895457260/code/src/main/java/litestruts/exception/XmlElementNotFoundException.java similarity index 100% rename from group01/895457260/code/src/litestruts/exception/XmlElementNotFoundException.java rename to group01/895457260/code/src/main/java/litestruts/exception/XmlElementNotFoundException.java diff --git a/group01/895457260/code/src/litestruts/struts.xml b/group01/895457260/code/src/main/java/litestruts/struts.xml similarity index 100% rename from group01/895457260/code/src/litestruts/struts.xml rename to group01/895457260/code/src/main/java/litestruts/struts.xml diff --git a/group01/895457260/code/src/algorithm/test/ArrayUtilTest.java b/group01/895457260/code/src/test/java/algorithm/ArrayUtilTest.java similarity index 99% rename from group01/895457260/code/src/algorithm/test/ArrayUtilTest.java rename to group01/895457260/code/src/test/java/algorithm/ArrayUtilTest.java index 85f04f3b31..8ea1f2e81a 100644 --- a/group01/895457260/code/src/algorithm/test/ArrayUtilTest.java +++ b/group01/895457260/code/src/test/java/algorithm/ArrayUtilTest.java @@ -1,4 +1,4 @@ -package algorithm.test; +package algorithm; import algorithm.ArrayUtil; import org.junit.Assert; diff --git a/group01/895457260/code/src/test/java/algorithm/lru/LRUPageFrameTest.java b/group01/895457260/code/src/test/java/algorithm/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..cfc6a7836c --- /dev/null +++ b/group01/895457260/code/src/test/java/algorithm/lru/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package algorithm.lru; + +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/group01/895457260/code/src/datastructure/test/ArrayListTest.java b/group01/895457260/code/src/test/java/datastructure/ArrayListTest.java similarity index 99% rename from group01/895457260/code/src/datastructure/test/ArrayListTest.java rename to group01/895457260/code/src/test/java/datastructure/ArrayListTest.java index 3a3f742634..907ea916ae 100644 --- a/group01/895457260/code/src/datastructure/test/ArrayListTest.java +++ b/group01/895457260/code/src/test/java/datastructure/ArrayListTest.java @@ -1,4 +1,4 @@ -package datastructure.test; +package datastructure; import datastructure.basic.ArrayList; import datastructure.basic.Iterator; diff --git a/group01/895457260/code/src/datastructure/test/BinarySortedTreeTest.java b/group01/895457260/code/src/test/java/datastructure/BinarySortedTreeTest.java similarity index 98% rename from group01/895457260/code/src/datastructure/test/BinarySortedTreeTest.java rename to group01/895457260/code/src/test/java/datastructure/BinarySortedTreeTest.java index f0374b2700..6419d73951 100644 --- a/group01/895457260/code/src/datastructure/test/BinarySortedTreeTest.java +++ b/group01/895457260/code/src/test/java/datastructure/BinarySortedTreeTest.java @@ -1,4 +1,4 @@ -package datastructure.test; +package datastructure; import datastructure.basic.BinarySortedTree; import datastructure.basic.BinaryTreeNode; diff --git a/group01/895457260/code/src/datastructure/test/LinkedListTest.java b/group01/895457260/code/src/test/java/datastructure/LinkedListTest.java similarity index 99% rename from group01/895457260/code/src/datastructure/test/LinkedListTest.java rename to group01/895457260/code/src/test/java/datastructure/LinkedListTest.java index d82cfa6ed5..dee34c8b3f 100644 --- a/group01/895457260/code/src/datastructure/test/LinkedListTest.java +++ b/group01/895457260/code/src/test/java/datastructure/LinkedListTest.java @@ -1,4 +1,4 @@ -package datastructure.test; +package datastructure; import datastructure.exception.EmptyListException; import datastructure.basic.LinkedList; diff --git a/group01/895457260/code/src/datastructure/test/QueueTest.java b/group01/895457260/code/src/test/java/datastructure/QueueTest.java similarity index 99% rename from group01/895457260/code/src/datastructure/test/QueueTest.java rename to group01/895457260/code/src/test/java/datastructure/QueueTest.java index 5a47f764a9..f2a9495484 100644 --- a/group01/895457260/code/src/datastructure/test/QueueTest.java +++ b/group01/895457260/code/src/test/java/datastructure/QueueTest.java @@ -1,4 +1,4 @@ -package datastructure.test; +package datastructure; import datastructure.exception.EmptyQueueException; import datastructure.basic.Queue; diff --git a/group01/895457260/code/src/datastructure/test/StackTest.java b/group01/895457260/code/src/test/java/datastructure/StackTest.java similarity index 98% rename from group01/895457260/code/src/datastructure/test/StackTest.java rename to group01/895457260/code/src/test/java/datastructure/StackTest.java index 24d7db58d8..ec3a8ed0a6 100644 --- a/group01/895457260/code/src/datastructure/test/StackTest.java +++ b/group01/895457260/code/src/test/java/datastructure/StackTest.java @@ -1,4 +1,4 @@ -package datastructure.test; +package datastructure; import datastructure.basic.*; import org.junit.Assert; diff --git a/group01/895457260/code/src/datastructure/test/TestSuite.java b/group01/895457260/code/src/test/java/datastructure/TestSuite.java similarity index 91% rename from group01/895457260/code/src/datastructure/test/TestSuite.java rename to group01/895457260/code/src/test/java/datastructure/TestSuite.java index d13bff3e5d..76ffdd40e0 100644 --- a/group01/895457260/code/src/datastructure/test/TestSuite.java +++ b/group01/895457260/code/src/test/java/datastructure/TestSuite.java @@ -1,4 +1,4 @@ -package datastructure.test; +package datastructure; import org.junit.runner.RunWith; import org.junit.runners.Suite; diff --git a/group01/895457260/code/src/test/java/download/FileDownloaderTest.java b/group01/895457260/code/src/test/java/download/FileDownloaderTest.java new file mode 100644 index 0000000000..4ce3158e98 --- /dev/null +++ b/group01/895457260/code/src/test/java/download/FileDownloaderTest.java @@ -0,0 +1,87 @@ +package download; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import download.api.ConnectionManager; +import download.impl.ConnectionManagerImpl; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class FileDownloaderTest { + private boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "file:///E:/Video/download/88993.mp4"; +// String url = "file:///E:/Pictures/Clannad/Clannad高清图片/38.jpg"; +// String url = "http://pic6.huitu.com/res/20130116/84481_20130116142820494200_1.jpg"; + + FileDownloader downloader = null; + try { + downloader = new FileDownloader(url); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail("wrong url"); + } + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setOnCompleteListener(() -> { + downloadFinished = true; + System.out.println("下载完成"); + }); + downloader.setOnFailListener(() -> { + downloadFinished = true; + System.out.println("下载失败"); + }); + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("正在下载…………"); + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private boolean actualContent(File downloaded, File source) { + String expected = readFile(downloaded); + String actual = readFile(source); + return expected.equals(actual); + } + + private String readFile(File file) { + int n; + StringBuilder builder = new StringBuilder(); + byte[] buf = new byte[1024]; + try { + InputStream is = new FileInputStream(file); + while ((n = is.read(buf)) != -1) { + for (int i = 0; i < n; ++i) { + builder.append(String.format("%d", buf[i])); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return builder.toString(); + } +} diff --git a/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java b/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java new file mode 100644 index 0000000000..ac48c1a4d6 --- /dev/null +++ b/group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java @@ -0,0 +1,61 @@ +package jvm; + +import jvm.exception.ReadClassException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileLoaderTest { + + private static ClassFileLoader loader; + private static String path1 = "target/classes"; + private static String path2 = "target/test-classes"; + + @Before + public void setUp() throws Exception { + loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + } + + @After + public void tearDown() throws Exception {} + + @Test + public void testClassPath() { + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1+";"+path2,clzPath); + } + + @Test + public void testClassFileLength() throws ReadClassException { + String className = "jvm.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1016, byteCodes.length); + } + + @Test + public void testMagicNumber() throws ReadClassException { + String className = "jvm.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[] {byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; + + String actualValue = this.byteToHexString(codes); + Assert.assertEquals("cafebabe", actualValue); + } + + private String byteToHexString(byte[] codes) { + StringBuilder buffer = new StringBuilder(); + for (byte b : codes) { + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } +} diff --git a/group01/895457260/code/src/test/java/jvm/EmployeeV1.java b/group01/895457260/code/src/test/java/jvm/EmployeeV1.java new file mode 100644 index 0000000000..0ab0e5bd1f --- /dev/null +++ b/group01/895457260/code/src/test/java/jvm/EmployeeV1.java @@ -0,0 +1,29 @@ +package jvm; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + } +} \ No newline at end of file diff --git a/group01/895457260/code/src/test/java/jvm/LiteJvmTest.java b/group01/895457260/code/src/test/java/jvm/LiteJvmTest.java new file mode 100644 index 0000000000..a6f36bb3ca --- /dev/null +++ b/group01/895457260/code/src/test/java/jvm/LiteJvmTest.java @@ -0,0 +1,83 @@ +package jvm; + +import jvm.exception.MagicNumberException; +import jvm.exception.ReadClassException; +import org.junit.Assert; +import org.junit.Test; +import org.junit.Before; +import org.junit.After; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * LiteJvm Tester. + * + * @author + * @version 1.0 + * @since
三月 26, 2017
+ */ +public class LiteJvmTest { + + private LiteJvm jvm = LiteJvm.INSTANCE; + private String fileName; + + @Before + public void before() throws Exception { + fileName = "target/classes/algorithm/ArrayUtil.class"; + } + + @After + public void after() throws Exception { + } + + /** + * Method: launch(File fileName) + */ + @Test + public void testLaunch() { +//TODO: Test goes here... + try { + jvm.launch(fileName); + } catch (MagicNumberException | ReadClassException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + } + + + /** + * Method: checkMagicNumber(byte[] bytes) + */ + @Test + public void testCheckMagicNumber() throws Exception { +//TODO: Test goes here... +// try { +// Method method = LiteJvm.class.getDeclaredMethod("checkMagicNumber", byte[].class); +// method.setAccessible(true); +// method.invoke(jvm, ???); +// } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { +// e.printStackTrace(); +// } + } + + /** + * Method: getBytes(File fileName) + */ + @Test + public void testGetBytes() throws Exception { +//TODO: Test goes here... + try { + Method method = LiteJvm.class.getDeclaredMethod("getBytes", File.class); + method.setAccessible(true); + byte[] bytes = (byte[]) method.invoke(jvm, fileName); + Assert.assertEquals(3851, bytes.length); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + } + +} diff --git a/group01/895457260/code/src/litestruts/test/StrutsTest.java b/group01/895457260/code/src/test/java/litestruts/StrutsTest.java similarity index 97% rename from group01/895457260/code/src/litestruts/test/StrutsTest.java rename to group01/895457260/code/src/test/java/litestruts/StrutsTest.java index 0129a8ad31..2526dc9354 100644 --- a/group01/895457260/code/src/litestruts/test/StrutsTest.java +++ b/group01/895457260/code/src/test/java/litestruts/StrutsTest.java @@ -1,4 +1,4 @@ -package litestruts.test; +package litestruts; import litestruts.Struts; import litestruts.View; diff --git a/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LRUPageFrame.java b/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LRUPageFrame.java new file mode 100644 index 0000000000..05961c124e --- /dev/null +++ b/group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LRUPageFrame.java @@ -0,0 +1,117 @@ +package com.aaront.exercise.basic; + +import java.util.Optional; + +/** + * 用双向链表实现LRU算法 + * + * @author tonyhui + */ +public class LRUPageFrame { + + private static class Node { + Node prev; + Node next; + int pageNum; + + Node() { + } + } + + private int capacity; + private int size = 0; + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + */ + public void access(int pageNum) { + Optional node = getNodeByPageNum(pageNum); + node.map(r -> { + delete(r); + addFirst(r); + return ""; + }).orElseGet(() -> { + Node newNode = new Node(); + newNode.pageNum = pageNum; + addFirst(newNode); + if (size >= capacity) { + delete(last); + } else { + size++; + } + return ""; + }); + } + + private Optional getNodeByPageNum(int pageNum) { + Node node = first; + while (node != null) { + if (node.pageNum == pageNum) return Optional.of(node); + node = node.next; + } + return Optional.empty(); + } + + private void delete(Node node) { + if (node == null) return; + if (node == first) { + deleteFirst(); + return; + } + if (node == last) { + deleteLast(); + return; + } + Node prevNode = node.prev; + Node nextNode = node.next; + prevNode.next = nextNode; + nextNode.prev = prevNode; + node.next = null; + node.prev = null; + } + + private void deleteFirst() { + if (first == null) return; + first = first.next; + first.prev = null; + } + + private void deleteLast() { + if (last == null) return; + last = last.prev; + last.next = null; + } + + private void addFirst(Node node) { + if (node == null) return; + if (first == null) { + first = node; + last = node; + } else { + node.next = first; + first.prev = node; + first = node; + } + } + + 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/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LRUPageFrameTest.java b/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LRUPageFrameTest.java new file mode 100644 index 0000000000..bad7c8b736 --- /dev/null +++ b/group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LRUPageFrameTest.java @@ -0,0 +1,32 @@ +package com.aaront.execrise.basic; + +import com.aaront.exercise.basic.LRUPageFrame; +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/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java index 8dcf538f42..a26a539a5b 100644 --- a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java +++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/DownloadThread.java @@ -2,31 +2,33 @@ import com.aaront.exercise.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; - byte[] content; + File file; public DownloadThread(Connection conn, int startPos, int endPos) { this.conn = conn; this.startPos = startPos; this.endPos = endPos; + this.file = new File("hehe.jpg"); } public void run() { try { - content = conn.read(startPos, endPos); + byte[] content = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile(file, "rw"); + raf.seek(startPos); + raf.write(content); } catch (IOException e) { e.printStackTrace(); } } - - public byte[] getContent() { - return this.content; - } } \ No newline at end of file diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java index 128292ea8e..d9231a7b15 100644 --- a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java +++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloader.java @@ -5,9 +5,6 @@ import com.aaront.exercise.api.ConnectionManager; import com.aaront.exercise.api.DownloadListener; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -64,14 +61,6 @@ public void execute() { e.printStackTrace(); } - try (FileOutputStream fos = new FileOutputStream(new File("temp.jpg"))) { - for(DownloadThread thread : threads) { - fos.write(thread.getContent()); - } - } catch (IOException e) { - e.printStackTrace(); - } - this.listener.notifyFinished(); } diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java index 6f75b3cd6c..60354d9ca2 100644 --- a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java +++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/FileDownloaderTest.java @@ -19,7 +19,8 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "http://localhost:8080/test.jpg"; + String url = "http://121.42.185.101/forum/test.jpg"; + //String url = "https://raw.githubusercontent.com/thlcly/coding2017/master/README.md"; FileDownloader downloader = new FileDownloader(url); ConnectionManager cm = new ConnectionManagerImpl(); downloader.setConnectionManager(cm); diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java index 5ad971c7c3..ffdb763201 100644 --- a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java +++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionImpl.java @@ -3,38 +3,45 @@ import com.aaront.exercise.api.Connection; import com.aaront.exercise.api.ConnectionException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; +import java.io.BufferedInputStream; import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; public class ConnectionImpl implements Connection { + private BufferedInputStream bis; + private int contentLength; - private FileInputStream fis; - private File file; - - public ConnectionImpl(String source) throws FileNotFoundException { - file = new File(getClass().getClassLoader().getResource(source).getFile()); - fis = new FileInputStream(file); + public ConnectionImpl(String url) throws IOException { + URLConnection connection = new URL(url).openConnection(); + bis = new BufferedInputStream(connection.getInputStream()); + contentLength = connection.getContentLength(); } @Override public byte[] read(int startPos, int endPos) throws IOException { - fis.skip(startPos); + long skipped = bis.skip(startPos); + while(skipped < startPos) { + skipped += bis.skip(startPos - skipped); + } byte[] content = new byte[endPos - startPos + 1]; - fis.read(content, 0, content.length); + int len = bis.read(content, 0, content.length); + while (len < content.length) { + len += bis.read(content, len, content.length - len); + System.out.println(len); + } return content; } @Override public int getContentLength() { - return (int)file.length(); + return contentLength; } @Override public void close() { try { - fis.close(); + bis.close(); } catch (IOException e) { throw new ConnectionException("连接关闭失败"); } diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java index a80c293176..7745aed166 100644 --- a/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java +++ b/group01/954958168/class03/MultiThreadDownload/src/main/java/com/aaront/exercise/impl/ConnectionManagerImpl.java @@ -4,25 +4,16 @@ import com.aaront.exercise.api.ConnectionException; import com.aaront.exercise.api.ConnectionManager; -import java.io.FileNotFoundException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.io.IOException; public class ConnectionManagerImpl implements ConnectionManager { @Override public Connection open(String url) throws ConnectionException { try { - return new ConnectionImpl(parse(url)); - } catch (FileNotFoundException e) { + return new ConnectionImpl(url); + } catch (IOException e) { throw new ConnectionException("创建连接失败"); } } - - private String parse(String url) { - String pattern = "(http|https)://[a-zA-Z0-9]+:[0-9]+/([a-zA-Z0-9.]+)"; - Matcher compile = Pattern.compile(pattern).matcher(url); - if(!compile.matches()) throw new ConnectionException("资源url不合法"); - return compile.group(2); - } } diff --git a/group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg b/group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg deleted file mode 100644 index 0eb7a002d8..0000000000 Binary files a/group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg and /dev/null differ diff --git a/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/ClassFileLoader.java b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..952bb76b00 --- /dev/null +++ b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/ClassFileLoader.java @@ -0,0 +1,64 @@ +package com.aaront.exercise.jvm.loader; + +import com.aaront.exercise.jvm.utils.string.FileUtils; +import com.aaront.exercise.jvm.utils.string.StringUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + String[] parts = _parseClassPath(className); + List files = _convertFromNameToFile(clzPaths); + for (int i = 0, len = parts.length; i < len; i++) { + files = _filterFileByName(files, parts[i]); + } + if (files.size() != 1) throw new IllegalArgumentException("className不合法"); + return _readFile(files.get(0)); + } + + public void addClassPath(String path) { + if (StringUtils.isEmpty(path)) return; + if (!FileUtils.isDictionary(path)) return; + clzPaths.add(path); + } + + public String getClassPath() { + return StringUtils.join(clzPaths, ";"); + } + + private String[] _parseClassPath(String className) { + String[] parts = className.split("\\."); + parts[parts.length - 1] = parts[parts.length - 1] + ".class"; + return parts; + } + + private List _convertFromNameToFile(List paths) { + return paths.stream().map(File::new).collect(Collectors.toList()); + } + + private List _filterFileByName(List paths, String name) { + return paths.stream().flatMap(path -> { + File[] files = path.listFiles(file -> file.getName().equals(name)); + if (files == null) return Stream.of(); + return Arrays.stream(files); + }).collect(Collectors.toList()); + } + + private byte[] _readFile(File file) throws IOException { + byte[] content = new byte[(int) file.length()]; + FileInputStream fis = new FileInputStream(file); + fis.read(content); + return content; + } +} diff --git a/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/EmployeeV1.java b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..adf66cddae --- /dev/null +++ b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.aaront.exercise.jvm.loader; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/FileUtils.java b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/FileUtils.java new file mode 100644 index 0000000000..770ebe5060 --- /dev/null +++ b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/FileUtils.java @@ -0,0 +1,16 @@ +package com.aaront.exercise.jvm.utils.string; + +import java.io.File; + +/** + * @author tonyhui + * @since 17/3/31 + */ +public class FileUtils { + + public static Boolean isDictionary(String path) { + File f = new File(path); + return f.isDirectory(); + } + +} diff --git a/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/StringUtils.java b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/StringUtils.java new file mode 100644 index 0000000000..f82971bbaa --- /dev/null +++ b/group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/StringUtils.java @@ -0,0 +1,40 @@ +package com.aaront.exercise.jvm.utils.string; + +/** + * @author tonyhui + * @since 17/3/31 + */ +public class StringUtils { + + public static Boolean isEmpty(CharSequence charSequence) { + if (charSequence == null) return true; + if (charSequence.length() == 0) return true; + int i = 0; + int len = charSequence.length(); + for (; i < len; i++) { + if (!Character.isWhitespace(charSequence.charAt(i))) break; + } + return i == len; + } + + public static String join(Object[] parts, String separator) { + StringBuilder sb = new StringBuilder(); + int len = parts.length; + for (int i = 0; i < len; i++) { + sb.append(parts[i]); + if (i != len - 1) { + sb.append(separator); + } + } + return sb.toString(); + } + + public static String join(Iterable iterable, final String separator) { + StringBuilder sb = new StringBuilder(); + iterable.forEach(r -> { + sb.append(r); + sb.append(separator); + }); + return sb.deleteCharAt(sb.length() - 1).toString(); + } +} diff --git a/group01/954958168/class04/mini-jvm/src/test/java/com/aaront/exercise/jvm/loader/ClassFileLoaderTest.java b/group01/954958168/class04/mini-jvm/src/test/java/com/aaront/exercise/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..45cce6ca72 --- /dev/null +++ b/group01/954958168/class04/mini-jvm/src/test/java/com/aaront/exercise/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,77 @@ +package com.aaront.exercise.jvm.loader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +/** + * @author tonyhui + * @since 17/3/31 + */ +public class ClassFileLoaderTest { + private static String path1 = "/Users/tonyhui/Code/coding2017/group01/954958168/class04/mini-jvm/target/classes"; + private static String path2 = "."; + + @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() throws IOException { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.aaront.exercise.jvm.loader.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1070, byteCodes.length); + + } + + + @Test + public void testMagicNumber() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.aaront.exercise.jvm.loader.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 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() { + + + } + +} diff --git a/group02/527705641/src/com/github/fei9009/coderising0305/download/impl/ConnectionManagerImpl.java b/group02/527705641/src/com/github/fei9009/coderising0305/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..8ef431ce0c --- /dev/null +++ b/group02/527705641/src/com/github/fei9009/coderising0305/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.github.fei9009.coderising0305.download.impl; + +import com.github.fei9009.coderising0305.download.api.Connection; +import com.github.fei9009.coderising0305.download.api.ConnectionException; +import com.github.fei9009.coderising0305.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return new ConnectionImpl(url); + } + +} diff --git a/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedList.java b/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedList.java index 1ed5923ee9..c1e8691a66 100644 --- a/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedList.java +++ b/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedList.java @@ -88,4 +88,135 @@ private static class Node{ } } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int length = size/ 2; + for (int i = 0; i < length; i++) { + head = head.next; + } + size = size - length; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if (i == 0) { + while (i < length) { + if (head == null) { + size = 0; + break; + } + head = head.next; + i++; + } + } + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] result = new int[list.size]; + for (int i = 0; i < result.length; i++) { + result[i] = (int)get((int)list.get(i)); + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + while (head.next != null && head.data == head.next.data) { + head = head.next; + size--; + } + Node dummy = head; + while (dummy.next != null) { + if (dummy.data == dummy.next.data) { + dummy.next = dummy.next.next; + size --; + } else { + dummy = dummy.next; + } + } + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if ((int)head.data > max) { + return ; + } + if ((int)get(size-1) < min) { + return; + } + while ((int)head.data > min && (int) head.data < max) { + head = head.next; + size--; + if (head == null) { + break; + } + } + Node dummy = head; + if (dummy == null) { + return; + } + while (dummy.next != null) { + if ((int)dummy.next.data > min && (int) dummy.next.data < max) { + dummy.next = dummy.next.next; + size --; + }else { + dummy = dummy.next; + } + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + return null; + } } diff --git a/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedListTest.java b/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedListTest.java index 1eb379a020..4f42f62e0a 100644 --- a/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedListTest.java +++ b/group02/527705641/src/com/github/fei9009/coding2017/basic/LinkedListTest.java @@ -1,16 +1,16 @@ package com.github.fei9009.coding2017.basic; import static org.junit.Assert.*; - import org.junit.Before; import org.junit.Test; -public class LinkedListTest { +public class LinkedListTest extends ListTest { + + private LinkedList aLinkedList; -private LinkedList aLinkedList; - @Before public void setUpLinkedList() { + aList = new LinkedList(); aLinkedList = new LinkedList(); } @@ -18,75 +18,331 @@ public void setUpLinkedList() { public void testAddFirst() { aLinkedList.addFirst(5); assertEquals(5, aLinkedList.get(0)); - + aLinkedList.addFirst(6); assertEquals(6, aLinkedList.get(0)); assertEquals(5, aLinkedList.get(1)); assertEquals(2, aLinkedList.size()); } - + @Test public void testAddLast() { aLinkedList.addLast("hello"); assertEquals("hello", aLinkedList.get(0)); - + aLinkedList.addLast("world"); assertEquals("hello", aLinkedList.get(0)); assertEquals("world", aLinkedList.get(1)); assertEquals(2, aLinkedList.size()); } - + @Test public void testRemoveFirst() { aLinkedList.addLast("hello"); aLinkedList.addLast("world"); - + aLinkedList.removeFirst(); assertEquals("world", aLinkedList.get(0)); assertEquals(1, aLinkedList.size()); - + aLinkedList.removeFirst(); assertEquals(0, aLinkedList.size()); } - + @Test public void testRemoveLast() { aLinkedList.addFirst("world"); aLinkedList.addFirst("hello"); - + aLinkedList.removeLast(); assertEquals("hello", aLinkedList.get(0)); assertEquals(1, aLinkedList.size()); - + aLinkedList.removeLast(); assertEquals(0, aLinkedList.size()); } - + @Test public void testLinkedListFunctional() { - for (int i=1; i<4; i++) { - aLinkedList.add(i); // [1,2,3] + for (int i = 1; i < 4; i++) { + aLinkedList.add(i); // [1,2,3] } - aLinkedList.remove(1); // [1,3] - - aLinkedList.add(1, 0); // [1,0,3] - for (int i=4; i<6; i++) { - aLinkedList.addFirst(i); // [5, 4, 1, 0, 3] + aLinkedList.remove(1); // [1,3] + + aLinkedList.add(1, 0); // [1,0,3] + for (int i = 4; i < 6; i++) { + aLinkedList.addFirst(i); // [5, 4, 1, 0, 3] } assertEquals(5, aLinkedList.size()); assertEquals(5, aLinkedList.get(0)); assertEquals(1, aLinkedList.get(2)); assertEquals(0, aLinkedList.get(3)); - - aLinkedList.remove(3); // [5, 4, 1, 3] - assertEquals(3, aLinkedList.get(aLinkedList.size()-1)); - aLinkedList.removeLast(); // [5, 4, 1] - assertEquals(1, aLinkedList.get(aLinkedList.size()-1)); - aLinkedList.removeFirst(); // [4,1] - + + aLinkedList.remove(3); // [5, 4, 1, 3] + assertEquals(3, aLinkedList.get(aLinkedList.size() - 1)); + aLinkedList.removeLast(); // [5, 4, 1] + assertEquals(1, aLinkedList.get(aLinkedList.size() - 1)); + aLinkedList.removeFirst(); // [4,1] + assertEquals(4, aLinkedList.get(0)); assertEquals(1, aLinkedList.get(1)); assertEquals(2, aLinkedList.size()); } + @Test + public void testReverse() { + // 测试当aLinkedList为空时的情况 + aLinkedList.reverse(); + assertEquals(0, aLinkedList.size()); + + // 测试当aLinkedList长度为1时的情况 + aLinkedList.add(4); + aLinkedList.reverse(); + assertEquals(1, aLinkedList.size()); + assertEquals(4, aLinkedList.get(0)); + + for (int i = 1; i < 4; i++) { + aLinkedList.add(i); // [4,1,2,3] + } + aLinkedList.reverse(); + assertEquals(4, aLinkedList.size()); + assertEquals(3, aLinkedList.get(0)); + assertEquals(2, aLinkedList.get(1)); + assertEquals(1, aLinkedList.get(2)); + assertEquals(4, aLinkedList.get(3)); + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10, 删除以后的值为7,8,10 + */ + @Test + public void testRemoveFirstHalf() { + aLinkedList.removeFirstHalf(); + assertEquals(0, aLinkedList.size()); + + aLinkedList.add(2); + aLinkedList.add(5); + aLinkedList.add(7); + aLinkedList.add(8); // [2,5,7,8] + + aLinkedList.removeFirstHalf(); // [7,8] + assertEquals(2, aLinkedList.size()); + assertEquals(7, aLinkedList.get(0)); + assertEquals(8, aLinkedList.get(1)); + + aLinkedList.add(10); // [7,8,10] + + aLinkedList.removeFirstHalf(); // [8,10] + assertEquals(2, aLinkedList.size()); + assertEquals(8, aLinkedList.get(0)); + assertEquals(10, aLinkedList.get(1)); + + aLinkedList.removeFirstHalf(); // [10] + aLinkedList.removeFirstHalf(); // [10] + assertEquals(1, aLinkedList.size()); + assertEquals(10, aLinkedList.get(0)); + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + @Test + public void testRemoveIntInt() { + for (int i = 0; i < 4; i++) { + aLinkedList.add(i); // [0,1,2,3] + } + + expectedEx.expect(Exception.class); + aLinkedList.remove(1, -1); + + expectedEx.expect(Exception.class); + aLinkedList.remove(-1, 1); + + aLinkedList.remove(0, 2); // [2,3] + assertEquals(2, aLinkedList.size()); + assertEquals(2, aLinkedList.get(0)); + assertEquals(3, aLinkedList.get(1)); + + aLinkedList.remove(1, 0); + aLinkedList.remove(0, 0); + assertEquals(2, aLinkedList.size()); + + aLinkedList.remove(1, 1); // [2] + assertEquals(1, aLinkedList.size()); + assertEquals(2, aLinkedList.get(0)); + + aLinkedList.remove(0, 1); // [] + assertEquals(0, aLinkedList.size()); + + expectedEx.expect(Exception.class); + aLinkedList.remove(1, 3); + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + @Test + public void testGetElements() { + for (int i = 0; i < 4; i++) { + aLinkedList.add(i * i); // [0,1,4,9] + } + + LinkedList bLinkedList = new LinkedList(); + int[] z1 = aLinkedList.getElements(bLinkedList); // [] + assertArrayEquals(new int[0], z1); + + bLinkedList.add(1); + bLinkedList.add(3); // [1, 3] + + z1 = aLinkedList.getElements(bLinkedList); // [1, 9] + assertArrayEquals(new int[] { 1, 9 }, z1); + + bLinkedList.add(1, 2); // bLinkedList = [1, 2, 3] + z1 = aLinkedList.getElements(bLinkedList); // [1, 4, 9] + assertArrayEquals(new int[] { 1, 4, 9 }, z1); + + bLinkedList.add(0, 0); // bLinkedList = [0, 1, 2, 3] + z1 = aLinkedList.getElements(bLinkedList); // [0, 1, 4, 9] + assertArrayEquals(new int[] { 0, 1, 4, 9 }, z1); + + // aLinkedList不应该变化 + assertEquals(4, aLinkedList.size()); + for (int i = 0; i < 4; i++) { + assertEquals(i * i, aLinkedList.get(i)); // [0,1,4,9] + } + + // Exception + bLinkedList.add(5); // bLinkedList = [0, 1, 2, 3, 5] + expectedEx.expect(Exception.class); + z1 = aLinkedList.getElements(bLinkedList); + } + + @Test + public void TestSubtract() { + // 传进的list为null,什么都不干 + LinkedList list = null; + for (int i = 0; i < 6; i++) { + aLinkedList.add(i); // [0,1,2,3,4,5] + } + aLinkedList.subtract(list); + assertEquals(6, aLinkedList.size()); + for (int i = 0; i < 6; i++) { + assertEquals(i, aLinkedList.get(i)); // [0,1,2,3,4,5] + } + + // 传进的list为空链表 + list = new LinkedList(); + aLinkedList.subtract(list); + assertEquals(6, aLinkedList.size()); + for (int i = 0; i < 6; i++) { + assertEquals(i, aLinkedList.get(i)); // [0,1,2,3,4,5] + } + + aLinkedList.add(1, 1); // [0,1,1,2,3,4,5] + aLinkedList.add(4, 3); // [0, 1, 1, 2, 3, 3, 4, 5] + + // list添加元素[0, 1, 3, 7] + list.add(0); + list.add(1); + list.add(3); + list.add(7); + + aLinkedList.subtract(list); // [2, 4, 5] + + assertEquals(3, aLinkedList.size()); + assertEquals(2, aLinkedList.get(0)); + assertEquals(4, aLinkedList.get(1)); + assertEquals(5, aLinkedList.get(2)); + } + + @Test + public void testRemoveDuplicateValues() { + aLinkedList.add(3); + aLinkedList.add(3); + aLinkedList.add(3); + aLinkedList.add(4); + aLinkedList.add(5); + aLinkedList.add(6); + aLinkedList.add(6); // [3, 3, 3, 4, 5, 6, 6] + + aLinkedList.removeDuplicateValues(); // [3, 4, 5, 6] + + assertEquals(4, aLinkedList.size()); + assertEquals(3, aLinkedList.get(0)); + assertEquals(4, aLinkedList.get(1)); + assertEquals(5, aLinkedList.get(2)); + assertEquals(6, aLinkedList.get(3)); + } + + @Test + public void testRemoveRange() { + for (int i = 0; i < 6; i++) { + aLinkedList.add(i); // [0, 1, 2, 3, 4, 5] //考虑重复元素 + } + aLinkedList.addFirst(0); // [0, 0, 1, 2, 3, 4, 5] + aLinkedList.add(3, 2); // [0, 0, 1, 2, 2, 3, 4, 5] + + aLinkedList.removeRange(1, 4); // 大于1小于4 [0, 0, 1, 4, 5] + + assertEquals(5, aLinkedList.size()); + assertEquals(0, aLinkedList.get(0)); + assertEquals(0, aLinkedList.get(1)); + assertEquals(1, aLinkedList.get(2)); + assertEquals(4, aLinkedList.get(3)); + assertEquals(5, aLinkedList.get(4)); + + // 若出现 min >= max的情况,什么都不做 + aLinkedList.removeRange(4, 1); + assertEquals(5, aLinkedList.size()); + assertEquals(0, aLinkedList.get(0)); + assertEquals(0, aLinkedList.get(1)); + assertEquals(1, aLinkedList.get(2)); + assertEquals(4, aLinkedList.get(3)); + assertEquals(5, aLinkedList.get(4)); + + // 将整个链表中的元素删除 + aLinkedList.removeRange(-1, 9); + assertEquals(0, aLinkedList.size()); + } + + @Test + public void testIntersection() { + for (int i = 0; i < 6; i++) { + aLinkedList.add(i); + } + aLinkedList.add(6); + aLinkedList.add(7); // [0, 1, 2, 3, 4, 5, 6, 7] + // list为null + LinkedList list = null; + LinkedList newList1 = aLinkedList.intersection(list); + assertNull(newList1); + + // list为空链表 + list = new LinkedList(); + LinkedList newList2 = aLinkedList.intersection(list); + assertEquals(0, newList2.size()); + + list.add(0); + list.add(3); + list.add(4); + list.add(7); + list.add(8); // [0, 3, 4, 7, 8] + LinkedList newList3 = aLinkedList.intersection(list); + + assertEquals(4, newList3.size()); + assertEquals(0, newList3.get(0)); + assertEquals(3, newList3.get(1)); + assertEquals(4, newList3.get(2)); + assertEquals(7, newList3.get(3)); + } } diff --git a/group02/527705641/src/com/github/fei9009/coding2017/basic/ListTest.java b/group02/527705641/src/com/github/fei9009/coding2017/basic/ListTest.java new file mode 100644 index 0000000000..acd43051f3 --- /dev/null +++ b/group02/527705641/src/com/github/fei9009/coding2017/basic/ListTest.java @@ -0,0 +1,93 @@ +package com.github.fei9009.coding2017.basic; + +import static org.junit.Assert.assertEquals; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + + +public class ListTest { + + protected static List aList; + + @Test + public void testFunctional() { + aList.add(1); + aList.add(2); + assertEquals(1, aList.get(0)); + assertEquals(2, aList.get(1)); + + aList.add(3); + aList.add(0, 5); + aList.add(2, 11); + assertEquals(5, aList.get(0)); + assertEquals(11, aList.get(2)); + + aList.add("hi"); + assertEquals("hi", aList.get(5)); + assertEquals(6, aList.size()); + + aList.remove(1); + assertEquals(11, aList.get(1)); + assertEquals(2, aList.get(2)); + + assertEquals(5, aList.size()); + } + + @Test + public void testAdd() { + for (int i = 0; i < 1000; i++) + aList.add(i); + assertEquals(0, aList.get(0)); + assertEquals(100, aList.get(100)); + assertEquals(999, aList.get(999)); + } + + @Test + public void testRemove() { + aList.add(1); + aList.add(2); + aList.add(3); + int u = (Integer)aList.remove(2); + assertEquals(3, u); + assertEquals(2, aList.size()); + + aList.add(1, 5); + u = (Integer)aList.remove(0); + assertEquals(1, u); + assertEquals(5, aList.get(0)); + assertEquals(2, aList.get(1)); + assertEquals(2, aList.size()); + + aList.remove(0); + aList.remove(0); + assertEquals(0, aList.size()); + + + } + + @Test + public void testSize() { + for (int i = 0; i < 10; i++) + aList.add(i * 2); + assertEquals(10, aList.size()); + } + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public void testException() { + expectedEx.expect(Exception.class); + aList.remove(1); + + aList.add(3); + + expectedEx.expect(Exception.class); + aList.add(2, 5); + } + + + +} diff --git a/group02/812350401/.gitignore b/group02/812350401/.gitignore index c24866af6d..0a2df7bbee 100644 --- a/group02/812350401/.gitignore +++ b/group02/812350401/.gitignore @@ -1,3 +1,4 @@ -/bin/ -/lib/ -/src/java_training +target/ +.idea/ +src/main/java/train/ +src/main/resources/ \ No newline at end of file diff --git a/group02/812350401/pom.xml b/group02/812350401/pom.xml new file mode 100644 index 0000000000..9a637781ce --- /dev/null +++ b/group02/812350401/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + coding2017 + 812350401 + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + + junit + junit + 4.12 + + + + dom4j + dom4j + 1.6.1 + + + + + \ No newline at end of file diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/ArrayList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/ArrayList.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/ArrayList.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/ArrayList.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/Iterator.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Iterator.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/Iterator.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Iterator.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/IteratorImp.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/IteratorImp.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/IteratorImp.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/IteratorImp.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/LinkedList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/LinkedList.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/LinkedList.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/LinkedList.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/List.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/List.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/List.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/List.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/Queue.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Queue.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/Queue.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Queue.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/Stack.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Stack.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/Stack.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Stack.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java similarity index 96% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java index 5d7ad8f4d3..41bc6ad344 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java @@ -171,7 +171,7 @@ private int[] getFactors(int num) { * 例如array= [3,8,9], seperator = "-" * 则返回值为"3-8-9" * @param array - * @param s + * @param seperator * @return */ public String join(int[] array, String seperator){ diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/DownloadThread.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/DownloadThread.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/DownloadThread.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/DownloadThread.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/FileDownloader.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/FileDownloader.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/FileDownloader.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/FileDownloader.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/Connection.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/Connection.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/Connection.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/Connection.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionException.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionException.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionException.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionException.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionManager.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionManager.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionManager.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionManager.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/DownloadListener.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/DownloadListener.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/api/DownloadListener.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/api/DownloadListener.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImpl.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImpl.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImpl.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImpl.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionManagerImpl.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionManagerImpl.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionManagerImpl.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionManagerImpl.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/LoginAction.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/LoginAction.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/LoginAction.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/LoginAction.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/LogoutAction.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/LogoutAction.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/LogoutAction.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/LogoutAction.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/Struts.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/Struts.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/Struts.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/Struts.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/View.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/View.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/View.java rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/View.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml rename to group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml diff --git a/group02/812350401/src/utils/ArrayUtils.java b/group02/812350401/src/main/java/utils/ArrayUtils.java similarity index 100% rename from group02/812350401/src/utils/ArrayUtils.java rename to group02/812350401/src/main/java/utils/ArrayUtils.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/ArrayListTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/ArrayListTest.java similarity index 57% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/ArrayListTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/ArrayListTest.java index b308c6bfef..934ecedcb2 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/ArrayListTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/ArrayListTest.java @@ -1,7 +1,6 @@ -package com.github.miniyk2012.coding2017.basic.test; +package com.github.miniyk2012.coding2017.basic; import org.junit.Before; -import com.github.miniyk2012.coding2017.basic.ArrayList; public class ArrayListTest extends ListTest { diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/BinaryTreeNodeTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/BinaryTreeNodeTest.java similarity index 97% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/BinaryTreeNodeTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/BinaryTreeNodeTest.java index 698506e2b5..205fbe3bb5 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/BinaryTreeNodeTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/BinaryTreeNodeTest.java @@ -1,4 +1,4 @@ -package com.github.miniyk2012.coding2017.basic.test; +package com.github.miniyk2012.coding2017.basic; import static org.junit.Assert.assertEquals; diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/LinkedListTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/LinkedListTest.java similarity index 98% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/LinkedListTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/LinkedListTest.java index 199e6a9a12..5ee2df36a2 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/LinkedListTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/LinkedListTest.java @@ -1,4 +1,4 @@ -package com.github.miniyk2012.coding2017.basic.test; +package com.github.miniyk2012.coding2017.basic; import static org.junit.Assert.*; @@ -6,9 +6,6 @@ import org.junit.Before; import org.junit.Test; -import com.github.miniyk2012.coding2017.basic.Iterator; -import com.github.miniyk2012.coding2017.basic.LinkedList; - public class LinkedListTest extends ListTest{ diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/ListTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/ListTest.java similarity index 97% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/ListTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/ListTest.java index b9f32fcc3b..87a8cdddb3 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/ListTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/ListTest.java @@ -1,4 +1,4 @@ -package com.github.miniyk2012.coding2017.basic.test; +package com.github.miniyk2012.coding2017.basic; import static org.junit.Assert.*; diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/QueueTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/QueueTest.java similarity index 92% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/QueueTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/QueueTest.java index 67035c1dcf..132334066a 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/QueueTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/QueueTest.java @@ -1,4 +1,4 @@ -package com.github.miniyk2012.coding2017.basic.test; +package com.github.miniyk2012.coding2017.basic; import static org.junit.Assert.*; import org.junit.Before; diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/StackTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/StackTest.java similarity index 92% rename from group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/StackTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/StackTest.java index a9b4e14afd..9fdde63598 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/test/StackTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/basic/StackTest.java @@ -1,4 +1,4 @@ -package com.github.miniyk2012.coding2017.basic.test; +package com.github.miniyk2012.coding2017.basic; import static org.junit.Assert.*; diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/array/test/ArrayUtilTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/array/ArrayUtilTest.java similarity index 98% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/array/test/ArrayUtilTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/array/ArrayUtilTest.java index 58de9f3efb..5e72c9ab5d 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/array/test/ArrayUtilTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/array/ArrayUtilTest.java @@ -1,4 +1,4 @@ -package com.github.miniyk2012.coding2017.coderising.array.test; +package com.github.miniyk2012.coding2017.coderising.array; import static org.junit.Assert.*; diff --git a/group02/812350401/src/test/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImplTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/download/ConnectionImplTest.java similarity index 86% rename from group02/812350401/src/test/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImplTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/download/ConnectionImplTest.java index 6007cf7b94..96892a86df 100644 --- a/group02/812350401/src/test/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImplTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/download/ConnectionImplTest.java @@ -1,13 +1,10 @@ -package test.com.github.miniyk2012.coding2017.coderising.download.impl; +package com.github.miniyk2012.coding2017.coderising.download; import com.github.miniyk2012.coding2017.coderising.download.api.Connection; -import com.github.miniyk2012.coding2017.coderising.download.impl.ConnectionImpl; import com.github.miniyk2012.coding2017.coderising.download.impl.ConnectionManagerImpl; -import org.junit.Test; -import org.junit.Before; import org.junit.After; - -import java.net.URL; +import org.junit.Before; +import org.junit.Test; /** * ConnectionImpl Tester. diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/FileDownloaderTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/download/FileDownloaderTest.java similarity index 100% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/download/FileDownloaderTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/download/FileDownloaderTest.java diff --git a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java similarity index 97% rename from group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java rename to group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java index 9443a32d97..15e569a766 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java +++ b/group02/812350401/src/test/java/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java @@ -10,9 +10,6 @@ import org.junit.Test; - - - public class StrutsTest { @Test diff --git a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/DownloadThread.java b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/DownloadThread.java index 115c1fab7e..5b357adff5 100644 --- a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/DownloadThread.java +++ b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/DownloadThread.java @@ -3,6 +3,11 @@ import rui.study.coding2017.jobs3.download.api.Connection; +import java.io.IOException; +import java.io.RandomAccessFile; + +import static rui.study.coding2017.jobs3.download.FileDownloader.getFilePath; + public class DownloadThread extends Thread{ Connection conn; @@ -10,12 +15,23 @@ public class DownloadThread extends Thread{ int endPos; public DownloadThread(Connection conn, int startPos, int endPos){ - - this.conn = conn; + this.conn = conn; this.startPos = startPos; this.endPos = endPos; } - public void run(){ - + @Override + public void run(){ + try { + byte[] bytes=conn.read(startPos,endPos); + RandomAccessFile randomAccessFile=new RandomAccessFile(getFilePath(),"rw"); + randomAccessFile.seek(startPos); + randomAccessFile.write(bytes); + randomAccessFile.close(); + } catch (IOException e) { + e.printStackTrace(); + }finally { + conn.close(); + } + } } diff --git a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/FileDownloader.java b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/FileDownloader.java index 48e982b9a4..433afb863e 100644 --- a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/FileDownloader.java +++ b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/FileDownloader.java @@ -6,68 +6,121 @@ import rui.study.coding2017.jobs3.download.api.ConnectionManager; import rui.study.coding2017.jobs3.download.api.DownloadListener; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; + public class FileDownloader { + + public static int threadNum=5; String url; DownloadListener listener; ConnectionManager cm; - + + private static String filePath; + + static String path="D:\\360downloads"; + + File pathFile; + + public static String getFilePath() { + return filePath; + } public FileDownloader(String _url) { this.url = _url; - + filePath=path+"/"+url.substring(url.lastIndexOf("/")+1); + + pathFile=new File(path); + if(!pathFile.exists()||!pathFile.isDirectory()){ + pathFile.mkdir(); + } } - + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + 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; + Connection conn = null; try { - conn = cm.open(this.url); - - int length = conn.getContentLength(); - - new DownloadThread(conn,0,length-1).start(); - + int length = conn.getContentLength(); + setRandomAccessFile(length); + List list = getDownloadThreads(conn, length); + waitForDownLoad(list); + listener.notifyFinished(); } catch (ConnectionException e) { e.printStackTrace(); - }finally{ + } 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; - } - + /** + * 配置 随机访问文件 + * 预分配文件所占的磁盘空间,磁盘中会创建一个指定大小的文件; + * @param length + * @throws IOException + */ + private void setRandomAccessFile(int length) throws IOException { + try { + RandomAccessFile randomAccessFile=new RandomAccessFile(filePath,"rw"); + randomAccessFile.setLength(length); + randomAccessFile.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * 获得下载线程,为下一步阻塞做准备 + * @param conn 连接 + * @param length 长度 + * @return + */ + private List getDownloadThreads(Connection conn, int length) { + int startPos; + int endPos; + List list=new ArrayList(); + for (int i = 0; i < threadNum; i++) { + //从0开始 + startPos=i*(length/threadNum); + //从length/threadNum开始,最后为所有长度 + endPos=(i==threadNum-1)?length-1:(i+1)*(length/threadNum); + + DownloadThread downloadThread=new DownloadThread(conn,startPos,endPos); + downloadThread.start(); + list.add(downloadThread); + } + return list; + } + + /** + * 阻塞线程列表,等待线程列表全部执行完成 + * @param list 线程列表 + */ + private void waitForDownLoad(List list) { + for (DownloadThread aList : list) { + try { + aList.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } } diff --git a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/api/ConnectionManager.java b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/api/ConnectionManager.java index be74c9b5dc..f1f2a7ae3f 100644 --- a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/api/ConnectionManager.java +++ b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/api/ConnectionManager.java @@ -1,10 +1,13 @@ package rui.study.coding2017.jobs3.download.api; +import java.io.IOException; +import java.net.MalformedURLException; + public interface ConnectionManager { /** * 给定一个url , 打开一个连接 * @param url * @return */ - public Connection open(String url) throws ConnectionException; + public Connection open(String url) throws ConnectionException, IOException; } diff --git a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionImpl.java b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionImpl.java index 3b85ecc27b..7e9b2c89f7 100644 --- a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionImpl.java +++ b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionImpl.java @@ -3,26 +3,55 @@ import rui.study.coding2017.jobs3.download.api.Connection; -import java.io.IOException; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; public class ConnectionImpl implements Connection { + private static int byteSize = 8 * 1024; + + private int contentLength; + + + private URL url; + + public ConnectionImpl(URL url) throws IOException { + this.url = url; + HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); + contentLength = httpURLConnection.getContentLength(); + httpURLConnection.disconnect(); + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + BufferedInputStream bufferedInputStream; + + ByteArrayOutputStream outputStream; + + HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); + httpURLConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + bufferedInputStream = new BufferedInputStream(httpURLConnection.getInputStream()); + outputStream = new ByteArrayOutputStream(); + int temp; + byte[] bytes = new byte[byteSize]; + while ((temp = bufferedInputStream.read(bytes)) != -1) { + outputStream.write(bytes, 0, temp); + } + bufferedInputStream.close(); + outputStream.flush(); + outputStream.close(); + httpURLConnection.disconnect(); + return outputStream.toByteArray(); + } + + @Override + public int getContentLength() { + return contentLength; + } + + @Override + public void close() { + } - @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/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionManagerImpl.java b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionManagerImpl.java index 89bc3cd0e7..a27d334b3d 100644 --- a/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionManagerImpl.java +++ b/group03/1360464792/src/main/java/rui/study/coding2017/jobs3/download/impl/ConnectionManagerImpl.java @@ -5,12 +5,14 @@ import rui.study.coding2017.jobs3.download.api.ConnectionException; import rui.study.coding2017.jobs3.download.api.ConnectionManager; +import java.io.IOException; +import java.net.URL; + public class ConnectionManagerImpl implements ConnectionManager { @Override - public Connection open(String url) throws ConnectionException { - - return null; + public Connection open(String url) throws ConnectionException, IOException { + return new ConnectionImpl(new URL(url)); } } diff --git a/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/FileDownloaderTest.java b/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/FileDownloaderTest.java similarity index 88% rename from group03/1360464792/src/test/java/rui/study/coding2017/jobs3/FileDownloaderTest.java rename to group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/FileDownloaderTest.java index 683051b778..3e95b7b593 100644 --- a/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/FileDownloaderTest.java +++ b/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/FileDownloaderTest.java @@ -1,4 +1,4 @@ -package rui.study.coding2017.jobs3; +package rui.study.coding2017.jobs3.download; import org.junit.After; import org.junit.Before; @@ -22,8 +22,8 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "http://localhost:8080/test.jpg"; - + String url = "http://sw.bos.baidu.com/sw-search-sp/software/952c9d6e73f50/QQ_8.9.20029.0_setup.exe"; + FileDownloader downloader = new FileDownloader(url); @@ -35,7 +35,6 @@ public void testDownload() { public void notifyFinished() { downloadFinished = true; } - }); @@ -52,9 +51,6 @@ public void notifyFinished() { } } System.out.println("下载完成!"); - - - } } diff --git a/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/impl/ConnectionImplTest.java b/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/impl/ConnectionImplTest.java new file mode 100644 index 0000000000..02206e79e0 --- /dev/null +++ b/group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/impl/ConnectionImplTest.java @@ -0,0 +1,39 @@ +package rui.study.coding2017.jobs3.download.impl; + +import org.junit.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; + +import static org.junit.Assert.*; + +/** + * 测试链接实现 + * Created by 赵睿 on 2017/3/15. + */ +public class ConnectionImplTest { + private String url="http://sw.bos.baidu.com/sw-search-sp/software/952c9d6e73f50/QQ_8.9.20029.0_setup.exe"; + + private ConnectionImpl connection=new ConnectionImpl(new URL(url)); + + public ConnectionImplTest() throws IOException { + } + + @Test + public void read() throws Exception { + byte[] bs=connection.read(0,connection.getContentLength()); + System.out.println(bs.length); + FileOutputStream fileOutputStream=new FileOutputStream(new File("D://eee.exe")); + fileOutputStream.write(bs); + fileOutputStream.flush(); + fileOutputStream.close(); + } + + @Test + public void getContentLength() throws Exception { + System.out.println(connection.getContentLength()); + } + +} \ No newline at end of file diff --git a/group03/345943980/download-0335/pom.xml b/group03/345943980/download-0335/pom.xml new file mode 100644 index 0000000000..b62ba3fec1 --- /dev/null +++ b/group03/345943980/download-0335/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + + org.hirisun.cm + download-0335 + 0.0.1-SNAPSHOT + jar + + download-0335 + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 4.10 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + + diff --git a/group03/345943980/download-0335/src/main/java/com/coderising/download/DownloadThread.java b/group03/345943980/download-0335/src/main/java/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..ec2a6adc0a --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/com/coderising/download/DownloadThread.java @@ -0,0 +1,47 @@ +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 localFile; + private CyclicBarrier barrier; + + public DownloadThread(Connection conn, int startPos, int endPos,String localFile, + CyclicBarrier barrier) { + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + + public void run() { + try { + System.out.println("Begin to read [" + startPos +"-"+endPos+"]"); + + byte[] data = conn.read(startPos, endPos); + + RandomAccessFile file = new RandomAccessFile(localFile,"rw"); + + file.seek(startPos); + + file.write(data); + + file.close(); + + conn.close(); + + barrier.await(); //等待别的线程完成 + + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/group03/345943980/download-0335/src/main/java/com/coderising/download/FileDownloader.java b/group03/345943980/download-0335/src/main/java/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..e6246d66ec --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/com/coderising/download/FileDownloader.java @@ -0,0 +1,157 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +public class FileDownloader { + + private static final int DOWNLOAD_TRHEAD_NUM = 3; + + private String url; + + private String localFile; + + private DownloadListener listener; + + private ConnectionManager cm; + + 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方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + /**Connection conn = null; + CountDownLatch threadsCnt = new CountDownLatch(threadNum); + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + RandomAccessFile file = new RandomAccessFile("test", "rw"); + file.setLength(length); + new DownloadThread(conn, 0, length - 1, file, threadsCnt).start(); + int clength = length / threadNum; + int off = 0; + for (int i = 0; i < threadNum; i++) { + if (i != threadNum - 1) { + new DownloadThread(cm.open(url), off, off + clength, file,threadsCnt).start(); + } else { + new DownloadThread(cm.open(url), off, length - 1, file,threadsCnt).start(); + } + off = off + clength + 1; + } + threadsCnt.await(); + Thread.sleep(5000); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + }**/ + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_TRHEAD_NUM , new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }); + + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + createPlaceHolderFile(this.localFile, length); + + int[][] ranges = allocateDownloadRange(DOWNLOAD_TRHEAD_NUM, length); + + for(int i=0; i< DOWNLOAD_TRHEAD_NUM; i++){ + + + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + + thread.start(); + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + } + + private int[][] allocateDownloadRange(int threadNum, int contentLen) { + + int[][] ranges = new int[threadNum][2]; + + int eachThreadSize = contentLen / threadNum;// 每个线程需要下载的文件大小 + int left = contentLen % threadNum;// 剩下的归最后一个线程来处理 + + for(int i=0;i totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + + public int getContentLength() { + + return httpConn.getContentLength(); + } + + public void close() { + + } +} diff --git a/group03/345943980/download-0335/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group03/345943980/download-0335/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..f89a2d9855 --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,29 @@ +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 { + + private Connection conn; + + public Connection open(String url) throws ConnectionException { + try { + URL urlObj = new URL(url); + HttpURLConnection httpConn = (HttpURLConnection)urlObj.openConnection(); + conn = new ConnectionImpl(httpConn); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return conn; + } + +} diff --git a/group03/345943980/download-0335/src/main/java/com/coding/basic/ArrayList.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..57412dcf7f --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/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/group03/345943980/download-0335/src/main/java/com/coding/basic/BinaryTreeNode.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..266eff3d56 --- /dev/null +++ b/group03/345943980/download-0335/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/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/Iterator.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/Iterator.java similarity index 61% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/Iterator.java rename to group03/345943980/download-0335/src/main/java/com/coding/basic/Iterator.java index 2d937d0c53..dbe8b9afb2 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/Iterator.java +++ b/group03/345943980/download-0335/src/main/java/com/coding/basic/Iterator.java @@ -1,7 +1,7 @@ -package com.github.eulerlcs.jmr.multiDL.algorithm; - -public interface Iterator { - public boolean hasNext(); - public Object next(); - -} +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group03/345943980/download-0335/src/main/java/com/coding/basic/LinkedList.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..fdc5eaa4ec --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/com/coding/basic/LinkedList.java @@ -0,0 +1,392 @@ +package com.coding.basic; + +import java.util.Stack; + +public class LinkedList implements List { + + private Node head; + private int size = 0; + + public void add(Object o) { + Node newNode = new Node(o); + if (null == head) { + head = newNode; + size++; + return; + } + Node currNode = head; + while (null != currNode.next) { + currNode = currNode.next; + } + currNode.next = newNode; + size++; + } + + public void add(int index, Object o) { + rangeCheck(index); + if (index == size) { + add(o); + return; + } + if (index == 0) { + Node newNode = new Node(o); + newNode.next = head; + head = newNode; + size++; + return; + } + Node newNode = new Node(o); + Node currNode = head; + for (int i = 0; i < index - 1; i++) { + currNode = currNode.next; + } + newNode.next = currNode.next; + currNode.next = newNode; + size++; + } + + public Object get(int index) { + rangeCheck(index); + Node node = head; + for (int i = 0; i < index; i++) { + node = node.next; + } + return node; + } + + private void rangeCheck(int index) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + } + + public Object remove(int index) { + rangeCheck(index); + if (index == 0) { + return this.removeFirst(); + } + if (index == size - 1) { + return this.removeLast(); + } + Node currNode = head; + for (int i = 0; i < index - 1; i++) { + currNode = currNode.next; + } + Node removeNode = currNode.next; + currNode.next = removeNode.next; + // removeNode = null; + size--; + return removeNode; + } + + public void remove(Object obj) { + if (head == null) { + throw new NullPointerException(); + } + // 如果要删除的结点是第一个,则把下一个结点赋值给第一个结点 + if (head.data.equals(obj)) { + head = head.next; + size--; + } else { + Node pre = head; // 上一节点 + Node cur = head.next; // 当前结点 + while (cur != null) { + if (cur.data.equals(obj)) { + pre.next = cur.next; + size--; + } + pre = pre.next; + cur = cur.next; + } + } + } + + public int size() { + return size; + } + + public void addFirst(Object o) { + if (null == head) { + head = new Node(o); + size++; + return; + } + Node newNode = new Node(o); + newNode.next = head; + head = newNode; + size++; + } + + public void addLast(Object o) { + this.add(o); + } + + public Object removeFirst() { + if (null == head) { + return null; + } + Node currNode = head; + head = currNode.next; + size--; + return head; + } + + public Object removeLast() { + if (null == head) { + return null; + } + if (null == head.next) { + Node currNode = head; + head = null; + size--; + return currNode; + } + Node currNode = head; + while (null != currNode.next) { + currNode = currNode.next; + } + currNode = null; + size--; + return null; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("["); + Node node = head; + while (node != null) { + sb.append(node.data); + if (node.next != null) { + sb.append(","); + } + node = node.next; + } + sb.append("]"); + return sb.toString(); + } + + public Iterator iterator() { + return new MyIterator(); + } + + private static class Node { + Object data; + Node next; + + Node(Object data) { + this.data = data; + } + + @Override + public String toString() { + return this.data.toString(); + } + } + + private class MyIterator implements Iterator { + int cursor = 0; + Node curNode; + + @Override + public boolean hasNext() { + return cursor != size; + } + + @Override + public Object next() { + if (curNode == null) { + curNode = head; + } else { + curNode = curNode.next; + } + cursor++; + return curNode; + } + + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (head == null || head.next == null) { + return; + } + java.util.Stack stack = new Stack<>(); + Node curNode = head; + while (curNode != null) { + stack.push(curNode); + Node nextNode = curNode.next; + curNode.next = null; // 断开指向下一个元素的指针 + curNode = nextNode; + } + + head = stack.pop(); + curNode = head; + while (!stack.isEmpty()) { + Node nextNode = stack.pop(); + curNode.next = nextNode; + curNode = 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++; + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = 11->101->201->301->401->501->601->701 listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + int[] arr = new int[list.size()]; + + for (int i = 0; i < list.size(); i++) { + arr[i] = Integer.parseInt(get(Integer.parseInt(list.get(i).toString())).toString()); + } + return arr; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + for (int i = 0; i < list.size(); i++) { + this.remove(list.get(i).toString()); + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (head == null || head.next == null) { + throw new RuntimeException("LinkedList is empty!"); + } + + Node pre = head; + Node cur = head; + while (cur.next != null) { + cur = cur.next; + Object data = pre.data; + while (cur.data == data) { + if (cur.next == null) { + pre.next = null; + break; + } + pre.next = cur.next; + size--; + cur = cur.next; + if (cur == null) { + break; + } + } + pre = pre.next; + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + + if (head == null) { + return; + } + + Node node = head; + int start = -1; + int end = -1; + int i = 0; + while (node != null) { + if ((start == -1) && (int) node.data <= min) { + start = i; + } + if ((int) node.data >= max) { + end = i; + break; + } + node = node.next; + i++; + } + + if (start == -1) { + start = 0; + } + if (end == -1) { + end = size; + } + this.remove(start, end - start); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + if (list == null) { + return null; + } + + LinkedList result = new LinkedList(); + + int i1 = 0; + int i2 = 0; + + while (i1 < this.size && i2 < list.size()) { + + int value1 = Integer.valueOf(this.get(i1).toString()); + int value2 = Integer.valueOf(list.get(i2).toString()); + + if (value1 == value2) { + result.add(value1); + i1++; + i2++; + + } else if (value1 < value2) { + i1++; + + } else { + i2++; + + } + } + return result; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/List.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/List.java similarity index 77% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/List.java rename to group03/345943980/download-0335/src/main/java/com/coding/basic/List.java index ad07c355b4..396b1f6416 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/List.java +++ b/group03/345943980/download-0335/src/main/java/com/coding/basic/List.java @@ -1,9 +1,9 @@ -package com.github.eulerlcs.jmr.multiDL.algorithm; - -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(); -} +package com.coding.basic; + +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/group03/345943980/download-0335/src/main/java/com/coding/basic/Queue.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/Queue.java new file mode 100644 index 0000000000..08d2d86b14 --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/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/group03/345943980/download-0335/src/main/java/com/coding/basic/Stack.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/Stack.java new file mode 100644 index 0000000000..4bfe28057f --- /dev/null +++ b/group03/345943980/download-0335/src/main/java/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/group03/345943980/download-0335/src/test/java/com/coderising/download/ConnectionTest.java b/group03/345943980/download-0335/src/test/java/com/coderising/download/ConnectionTest.java new file mode 100644 index 0000000000..705197e55d --- /dev/null +++ b/group03/345943980/download-0335/src/test/java/com/coderising/download/ConnectionTest.java @@ -0,0 +1,20 @@ +package com.coderising.download; + +import org.junit.Assert; +import org.junit.Test; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class ConnectionTest { + + @Test + public void testContentLength() throws ConnectionException{ + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection con = connMan.open("https://imgsa.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=befb30b3a344ad343ab28fd5b1cb6791/1ad5ad6eddc451daae139eb5b4fd5266d1163282.jpg"); + Assert.assertEquals(90441, con.getContentLength()); + + } +} diff --git a/group03/345943980/download-0335/src/test/java/com/coderising/download/FileDownloaderTest.java b/group03/345943980/download-0335/src/test/java/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..088d2fbe39 --- /dev/null +++ b/group03/345943980/download-0335/src/test/java/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,42 @@ +package com.coderising.download; + +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 { + + private boolean downloadFinished = false; + + @Test + public void testDownloader() { + String url = "https://imgsa.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=befb30b3a344ad343ab28fd5b1cb6791/1ad5ad6eddc451daae139eb5b4fd5266d1163282.jpg"; + FileDownloader downloader = new FileDownloader(url,"D:\\wordtest\\test123.jpg"); + + 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/group03/345943980/download-0335/src/test/java/com/coderising/download/TestLinkedList.java b/group03/345943980/download-0335/src/test/java/com/coderising/download/TestLinkedList.java new file mode 100644 index 0000000000..ddbb09a332 --- /dev/null +++ b/group03/345943980/download-0335/src/test/java/com/coderising/download/TestLinkedList.java @@ -0,0 +1,245 @@ +package com.coderising.download; + +import org.junit.Assert; +import org.junit.Test; + +import com.coding.basic.Iterator; +import com.coding.basic.LinkedList; + +public class TestLinkedList { + + + + @Test + public void testAdd(){ + LinkedList linkedList = new LinkedList(); + linkedList.add("123"); //0 + //1 + //2 + linkedList.add("233"); //3 + linkedList.add("333"); //4 + + linkedList.add("444"); //5 + + //System.out.println(linkedList.get(3)); + //System.out.println(linkedList.get(4)); + + linkedList.add(0,"555"); + linkedList.add(2,"666"); + linkedList.add(5,"777"); + + +// for(int i=0;idom4j 1.6.1 + + + org.jdom + jdom2 + 2.0.5 + diff --git a/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Configuration.java b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Configuration.java new file mode 100644 index 0000000000..23b23c6495 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Configuration.java @@ -0,0 +1,105 @@ +package com.coderising.teacher.litestruts; + +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 { + private static final String LINE = "/"; + private Map actions = new HashMap<>(); + + public Configuration(String fileName) { + + /*String packageName = this.getClass().getPackage().getName(); + packageName = packageName.replace(".", LINE); + InputStream is = this.getClass().getResourceAsStream(LINE + packageName + LINE + fileName); + parseXML(is); + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + }*/ + + InputStream is = this.getClass().getResourceAsStream(LINE+fileName); + parseXML(is); + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + 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.getTextTrim(); + ac.addViewResult(resultName, viewName); + } + this.actions.put(actionName, ac); + } + } catch (JDOMException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String getClassName(String action) { + ActionConfig ac = this.actions.get(action); + if (ac == null) { + return null; + } + return ac.getClzName(); + } + + 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 void addViewResult(String name, String viewName) { + viewResult.put(name, viewName); + } + + public String getViewName(String resultName) { + return viewResult.get(resultName); + } + + public String getClzName() { + return clzName; + } + + } +} diff --git a/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ConfigurationException.java b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..4698e65cc7 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ConfigurationException.java @@ -0,0 +1,23 @@ +package com.coderising.teacher.litestruts; + +import java.io.IOException; + +import org.jdom2.JDOMException; + +public class ConfigurationException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } + +} diff --git a/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/LoginAction.java b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/LoginAction.java new file mode 100644 index 0000000000..3b70f5e4d8 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/LoginAction.java @@ -0,0 +1,41 @@ +package com.coderising.teacher.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/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ReflectionUtil.java b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..9ae358c964 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ReflectionUtil.java @@ -0,0 +1,72 @@ +package com.coderising.teacher.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; + + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + /*List listMethods = new ArrayList<>(); + Method[] methods = clz.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().startsWith("set")) { + listMethods.add(method); + } + } + return listMethods;*/ + return getMethod(clz,"set"); + } + + public static void setParameters(Object o, Map params) { + List methods = ReflectionUtil.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 | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + + } + } + + public static List getGetterMethods(Class clz) { + return getMethod(clz,"get"); + } + + public static List getMethod(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 obj) { + Map params = new HashMap(); + List methods = ReflectionUtil.getGetterMethods(obj.getClass()); + for(Method m:methods){ + try { + Object o = m.invoke(obj); + params.put(m.getName().replace("get","").toLowerCase(), o); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + return params; + } + + + +} diff --git a/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Struts.java b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Struts.java new file mode 100644 index 0000000000..e623c8530f --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Struts.java @@ -0,0 +1,52 @@ +package com.coderising.teacher.litestruts; + +import java.lang.reflect.Method; +import java.util.Map; + +public class Struts { + + static Configuration config = new Configuration("struts1.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 = config.getClassName(actionName); + if(clzName == null){ + return null; + } + try { + Class clz = Class.forName(clzName); + Object obj = clz.newInstance(); + ReflectionUtil.setParameters(obj, parameters); + Method method = clz.getDeclaredMethod("execute"); + String resultName = (String)method.invoke(obj); + Map params = ReflectionUtil.getParamterMap(obj); + String resultView = config.getResultView(actionName, resultName); + View view = new View(); + view.setJsp(resultView); + view.setParameters(params); + return view; + } catch (Exception e) { + + e.printStackTrace(); + } + return null; + } +} diff --git a/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/View.java b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/View.java new file mode 100644 index 0000000000..859da491e2 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/View.java @@ -0,0 +1,26 @@ +package com.coderising.teacher.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/group03/345943980/lite-struts-0226/src/main/resources/struts1.xml b/group03/345943980/lite-struts-0226/src/main/resources/struts1.xml new file mode 100644 index 0000000000..7fb755e61f --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/main/resources/struts1.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/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ConfigurationTest.java b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..3e3afca449 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,36 @@ +package com.coderising.litestruts; + +import org.junit.Assert; +import org.junit.Test; + +import com.coderising.teacher.litestruts.Configuration; + +public class ConfigurationTest { + Configuration cfg = new Configuration("struts1.xml"); + + @Test + public void testGetClassName() { + + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.coderising.teacher.litestruts.LoginAction", clzName); + + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.coderising.teacher.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/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..b2814f0302 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,100 @@ +package com.coderising.litestruts; + +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.Assert; +import org.junit.Test; + +import com.coderising.teacher.litestruts.ReflectionUtil; + +public class ReflectionUtilTest { + + @Test + public void testGetSetterMethod() throws Exception { + + String name = "com.coderising.teacher.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.teacher.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.teacher.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.teacher.litestruts.LoginAction"; + Class clz = Class.forName(name); + com.coderising.teacher.litestruts.LoginAction action = (com.coderising.teacher.litestruts.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/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest.java b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest.java index 505e2afbfa..70618cc246 100644 --- a/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest.java +++ b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest.java @@ -6,33 +6,35 @@ 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")); + + 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")); + 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/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest1.java b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest1.java new file mode 100644 index 0000000000..22cb65fe59 --- /dev/null +++ b/group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest1.java @@ -0,0 +1,38 @@ +package com.coderising.litestruts; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class StrutsTest1 { + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + com.coderising.teacher.litestruts.View view = com.coderising.teacher.litestruts.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"); //密码和预设的不一致 + + com.coderising.teacher.litestruts.View view = com.coderising.teacher.litestruts.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/group03/58555264/src/main/java/com/circle/collection/LinkedListV2.java b/group03/58555264/src/main/java/com/circle/collection/LinkedListV2.java new file mode 100644 index 0000000000..6fbc5c0b14 --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/collection/LinkedListV2.java @@ -0,0 +1,414 @@ +package com.circle.collection; + +import java.util.*; + +/** + * Created by keweiyang on 2017/3/13. + */ +public class LinkedListV2 { + + private int size; + private Node first; + + /** + * 从尾部插入数据 + * + * @param e + */ + public void add(E e) { + Node node = new Node(e, null); + if (size == 0) { + first = node; + } else { + Node current = first; + while (current.next != null) { + current = current.next; + } + current.next = node; + } + size++; + } + + public void add(int index, E e) { + rangeCheck(index); + Node node = new Node(e, null); + Node current = first; + Node prev = null; + if (index == 0) { + node.next = first; + first = node; + } else { + int i = 1; + prev = current; + current = current.next; + while (current != null) { + + if (i == index) { + break; + } + i++; + prev = current; + current = current.next; + + } + node.next = current; + prev.next = node; + + } + size++; + } + + public E get(int index) { + rangeCheck(index); + Node current = first; + + int i = 0; + if (current == null) { + throw new NoSuchElementException("链表为空"); + } else { + while (current.next != null) { + + if (i == index) { + break; + } + i++; + current = current.next; + } + } + return (E) current.item; + } + + private void rangeCheck(int index) { + if (index > size || index < 0) { + throw new IndexOutOfBoundsException("索引越界"); + } + } + + public int size() { + return this.size; + } + + + public E removeFirst() { + if (first == null) { + throw new IllegalStateException("链表为空"); + } else { + Node current = first; + first = first.next; + size--; + return (E) current.item; + } + } + + public E removeLast() { + if (first == null) { + throw new IllegalStateException("链表为空"); + } else { + Node current = first; + while (current.next != null) { + current = current.next; + } + size--; + return (E) current.item; + + } + } + + /** + * 把该链表逆置 + * 例如链表为3->7->10,逆置后变为 10->7->3 + */ + public void reverse() { + Node current = first; + LinkedListV2 list = new LinkedListV2(); + while (current != null) { + + list.add(0, current.item); + current = current.next; + } + + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list=2->5->7->8,删除以后的值为 7->8 + * 如果 list=2->5->7->8 ->10,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + Node stepByOne = first; + Node stepByTwo = first; + + while (stepByTwo.next != null && stepByTwo.next.next != null) { + + stepByTwo = stepByTwo.next.next; + stepByOne = stepByOne.next; + } + + if (stepByTwo.next != null) { + stepByOne = stepByOne.next; + } + + //打印单链表的前半部分 + while (stepByOne != null) { + System.out.println(String.valueOf(stepByOne.item)); + stepByOne = stepByOne.next; + + } + + + } + + /** + * 从第i个元素开始,删除length个元素,注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + rangeCheck(i); + if (length <= 0) { + throw new IllegalStateException("请输入正确的个数"); + } + Node current = first; + Node prev = null; + int a = 0; + while (current != null) { + prev = current; + current = current.next; + a++; + if (a == i) { + break; + } + } + + if ((size - i + 1) <= length) { + prev.next = null; + size -= (size - i); + } else { + Node node = prev; + int temp = length; + while (temp > 0) { + current = current.next; + temp--; + } + prev.next = current; + size -= length; + + } + + + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出哪些list所指定的元素 + * 例如当前链表=11->101->201->301->401->501->601->701 + * listB =1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + * @return + */ + public E[] getElements(LinkedListV2 list) { + + Iterator it = list.iterator(); + LinkedListV2 getElementsList = new LinkedListV2(); + while (it.hasNext()) { + Integer integer = (Integer) it.next(); + E e = get(integer); + getElementsList.add(e); + } + + + return (E[]) getElementsList.toArray(); + } + + public Object[] toArray() { + Object[] result = new Object[size]; + + int i = 0; + for (Node x = first; x != null; x = x.next) { + result[i] = x.item; + i++; + } + + return result; + } + + /** + * 已知链表的元素以值递增有序排列,并以单链表做存储结构 + * 从当前链表中删除在list中出现的元素 + * + * @param list + */ + public void subtract(LinkedListV2 list) { + Iterator it = list.iterator(); + Node current = first; + Node prev = null; + + while (it.hasNext()) { + Integer integer = (Integer) it.next(); + + + while (integer > (Integer) (current.item) && current != null) { + prev = current; + current = current.next; + } + + if (current != null && integer.equals(current.item)) { + if (current == first) { + first = first.next; + current = first; + } else { + prev.next = current.next; + current = current.next; + } + size--; + } else { + System.out.println("该链表中没有该元素"); + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表做存储结构 + * 删除表中所有值相同的多余元素 + */ + public void removeDuplicateValues() { + Node current = first; + Node innerCurrent = null; + while (current != null) { + + innerCurrent = current.next; + while (innerCurrent != null) { + if (!(innerCurrent.item).equals(current.item)) { + break; + } + innerCurrent = innerCurrent.next; + size--; + } + + current.next = innerCurrent; + current = current.next; + + } + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作为存储结构 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + Node current = first; + Node prev = first; + while (current != null) { + if ((Integer)(current.item) > min && (Integer)(current.item) < max) { + if (current == first) { + first = first.next; + current = first; + prev = first; + }else{ + prev.next = current.next; + + } + size--; + } + prev = current; + current = current.next; + } + + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C的元素有依值递增有序排列 + * + * @param list + * @return + */ + public LinkedListV2 intersection(LinkedListV2 list) { + + Iterator it = list.iterator(); + Node current = first; + + LinkedListV2 newList = new LinkedListV2(); + + if (list.size == 0 || this.size == 0) { + return null; + } + + if ((Integer) this.first.item > (Integer) list.get(list.size() - 1)) { + return null; + } + + if ((Integer) this.removeLast() < (Integer) list.get(0)) { + return null; + } + + while (it.hasNext()) { + Integer integer = (Integer) it.next(); + + while (current != null && integer > (Integer) (current.item)) { +// prev = current; + current = current.next; + } + + if (current != null && integer.equals(current.item)) { + newList.add(current.item); + + } + } + + + return newList; + } + + + private static class Node { + E item; + Node next; + + public Node(E item, Node next) { + this.item = item; + this.next = next; + } + } + + public Iterator iterator() { + return new Iterator() { + int nextIndex = 0; + + @Override + public boolean hasNext() { + return nextIndex < size; + } + + @Override + public E next() { + if (!this.hasNext()) { + throw new NoSuchElementException(); + } + E e = get(nextIndex); + nextIndex++; + + return e; + } + }; + } + + + public static void main(String[] args) { + java.util.LinkedList list; + + } +} diff --git a/group03/58555264/src/main/java/com/circle/download/DownloadThread.java b/group03/58555264/src/main/java/com/circle/download/DownloadThread.java new file mode 100644 index 0000000000..1f3b996dde --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/DownloadThread.java @@ -0,0 +1,54 @@ +package com.circle.download; + +import com.circle.download.api.Connection; +import com.circle.download.api.ConnectionException; +import com.circle.download.api.DownloadListener; + +import java.io.*; + +/** + * Created by keweiyang on 2017/3/10. + */ +public class DownloadThread extends Thread { + + private Connection conn; + private int startPos; + private int endPos; + static int threadFinished = 0; + + private DownloadListener listener; + private int threadNum; + + + public DownloadThread(Connection conn, int startPos, int endPos, DownloadListener listener, int threadNum) { + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.listener = listener; + this.threadNum = threadNum; + } + + @Override + public void run() { + try { + this.conn.read(startPos, endPos); + } catch (IOException e) { + e.printStackTrace(); + } catch (ConnectionException e) { + e.printStackTrace(); + } finally { + synchronized (this) { + threadFinished++; + if (threadFinished == threadNum) { + listener.notifyFinished(); + } + + } + + } + System.out.println("线程:" + Thread.currentThread().getId() + " , startPos:" + startPos + ",endPos:" + endPos); + + } +} + diff --git a/group03/58555264/src/main/java/com/circle/download/FileDownloader.java b/group03/58555264/src/main/java/com/circle/download/FileDownloader.java new file mode 100644 index 0000000000..ac7e3e3ef3 --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/FileDownloader.java @@ -0,0 +1,106 @@ +package com.circle.download; + +import com.circle.download.api.Connection; +import com.circle.download.api.ConnectionException; +import com.circle.download.api.ConnectionManager; +import com.circle.download.api.DownloadListener; +import com.circle.download.impl.ConnectionManagerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Created by keweiyang on 2017/3/10. + */ +public class FileDownloader { + private String url; + private DownloadListener listener; + private ConnectionManager cm; + private int threadNum; + + public FileDownloader(String url, int threadNum) { + this.threadNum = threadNum; + this.url = url; + } + + public DownloadListener getListener() { + return listener; + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + /** + * 具体的实现思路: + * 1、需要调用ConnectionManager的open方法打开连接,然后通过Connection.getConnection.getContentLength方法获得文件的长度 + * 2、至少启动3个线程下载,注意每个线程需要调用ConnectionManager的open方法 + * 然后调用read方法,read方法中有读取文件的开始位置和结束位置的参数,返回值是byte[]数组 + * 3、把byte数组写入到文件中 + * 4、所有的线程都下载完成以后,需要调用listener的notifiedFinished方法 + */ + public void execute() { + Connection conn = null; + int[] startPos = new int[threadNum]; + int[] endPos = new int[threadNum]; + RandomAccessFile raf = null; + + try { + String[] ss = url.split("/"); + Thread[] threads = new Thread[threadNum]; + + File file = new File(ss[ss.length - 1]); + + + cm = ConnectionManagerFactory.getManager(file); + conn = cm.open(this.url); + int length = conn.getContentLength(); + System.out.println("length:" + length); + + + raf = new RandomAccessFile(file, "rwd"); + raf.setLength(length); + + for (int i = 0; i < threadNum; i++) { + int size = i * (length / threadNum); + startPos[i] = size; + + if (i == threadNum - 1) { + endPos[i] = length; + } else { + size = (i + 1) * (length / threadNum); + endPos[i] = size - 1; + } + + threads[i] = new DownloadThread(cm.open(this.url), startPos[i], endPos[i],listener,threadNum); + threads[i].start(); + } + } catch (ConnectionException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + if (raf != null) { + try { + raf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + public static void main(String[] args) { + String url2 = "http://hiphotos.baidu.com/240728057/pic/item/6a50e38242aad8f60cf4d2b3.jpg"; + String url = "http://bcbang.oss-cn-qingdao.aliyuncs.com/TLAB-in-Eden-memory.png"; + String url3 = "http://www.cnblogs.com/iwideal/p/6045118.html"; + FileDownloader downloader = new FileDownloader(url2, 2); + downloader.execute(); + + } + +} diff --git a/group03/58555264/src/main/java/com/circle/download/api/Connection.java b/group03/58555264/src/main/java/com/circle/download/api/Connection.java new file mode 100644 index 0000000000..518f87f5c5 --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/api/Connection.java @@ -0,0 +1,31 @@ +package com.circle.download.api; + +import java.io.IOException; + +/** + * Created by keweiyang on 2017/3/10. + */ +public interface Connection { + + /** + * 给定开始和结束位置,读取数据,返回值是字节数组 + * + * @param startPos 开始位置,从0开始 + * @param endPos 结束位置 + * @return + * @throws IOException + */ + public void read(int startPos, int endPos) throws IOException, ConnectionException; + + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); + +} diff --git a/group03/58555264/src/main/java/com/circle/download/api/ConnectionException.java b/group03/58555264/src/main/java/com/circle/download/api/ConnectionException.java new file mode 100644 index 0000000000..b0f013308d --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/api/ConnectionException.java @@ -0,0 +1,24 @@ +package com.circle.download.api; + +/** + * Created by keweiyang on 2017/3/10. + */ +public class ConnectionException extends Exception { + + public ConnectionException() { + + } + + /** + * 描述异常 + * @param msg + */ + public ConnectionException(String msg) { + super(msg); + + } +} + + + + diff --git a/group03/58555264/src/main/java/com/circle/download/api/ConnectionManager.java b/group03/58555264/src/main/java/com/circle/download/api/ConnectionManager.java new file mode 100644 index 0000000000..8de4d600ba --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/api/ConnectionManager.java @@ -0,0 +1,12 @@ +package com.circle.download.api; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.sql.*; + +/** + * Created by keweiyang on 2017/3/10. + */ +public interface ConnectionManager { + public Connection open(String url) throws ConnectionException, IOException; +} diff --git a/group03/58555264/src/main/java/com/circle/download/api/DownloadListener.java b/group03/58555264/src/main/java/com/circle/download/api/DownloadListener.java new file mode 100644 index 0000000000..758b233d3c --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/api/DownloadListener.java @@ -0,0 +1,8 @@ +package com.circle.download.api; + +/** + * Created by keweiyang on 2017/3/10. + */ +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group03/58555264/src/main/java/com/circle/download/impl/ConnectionImpl.java b/group03/58555264/src/main/java/com/circle/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..c528d3b335 --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/impl/ConnectionImpl.java @@ -0,0 +1,77 @@ +package com.circle.download.impl; + +import com.circle.download.api.Connection; +import com.circle.download.api.ConnectionException; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * Created by keweiyang on 2017/3/10. + */ +class ConnectionImpl implements Connection { + private String url; + private HttpURLConnection conn; + private File file; + + public ConnectionImpl(String url, File file) throws IOException, ConnectionException { + this.file = file; + this.url = url; + this.conn = init(); + } + + private HttpURLConnection init() throws IOException, ConnectionException { + URL httpURL = new URL(url); + this.conn = (HttpURLConnection) httpURL.openConnection(); + + this.conn.setRequestMethod("GET"); + this.conn.setRequestProperty("Charset", "UTF-8"); + return conn; + } + + @Override + public void read(int startPos, int endPos) throws IOException, ConnectionException { + URL httpURL = new URL(url); + this.conn = (HttpURLConnection) httpURL.openConnection(); + + this.conn.setRequestMethod("GET"); + this.conn.setRequestProperty("Charset", "UTF-8"); + this.conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + if (this.getContentLength() < 0) { + throw new ConnectionException("连接内容小于0"); + } + + int code = conn.getResponseCode(); + RandomAccessFile raf = null; + try{ + InputStream is = conn.getInputStream(); + raf = new RandomAccessFile(this.file, "rwd"); + raf.seek(startPos); + + byte[] bs = new byte[1024]; + int len = -1; + + while ((len = is.read(bs)) != -1) { + raf.write(bs, 0, len); + } + }finally { + raf.close(); + } + + + + } + + @Override + public int getContentLength() { + return this.conn.getContentLength(); + } + + @Override + public void close() { +// this.conn. + + } +} diff --git a/group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerFactory.java b/group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerFactory.java new file mode 100644 index 0000000000..b879683ba9 --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerFactory.java @@ -0,0 +1,31 @@ +package com.circle.download.impl; + +import com.circle.download.api.Connection; +import com.circle.download.api.ConnectionManager; + +import java.io.File; + +/** + * Created by keweiyang on 2017/3/11. + */ +public class ConnectionManagerFactory { + + private static volatile ConnectionManager manager = null; + + private ConnectionManagerFactory() { + + } + + public static ConnectionManager getManager(File file) { + + if (manager == null) { + synchronized (ConnectionManagerFactory.class) { + if (manager == null) { + manager = new ConnectionManagerImpl(file); + } + } + } + + return manager; + } +} diff --git a/group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerImpl.java b/group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..6013f8878b --- /dev/null +++ b/group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,31 @@ +package com.circle.download.impl; + +import com.circle.download.api.Connection; +import com.circle.download.api.ConnectionException; +import com.circle.download.api.ConnectionManager; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +/** + * Created by keweiyang on 2017/3/10. + */ +class ConnectionManagerImpl implements ConnectionManager { + private File file; + + public ConnectionManagerImpl(File file) { + + this.file = file; + + } + + @Override + public Connection open(String url) throws ConnectionException, IOException { + return new ConnectionImpl(url, this.file); + } + + +} diff --git a/group03/58555264/src/test/java/com/circle/collection/LinkedListV2Test.java b/group03/58555264/src/test/java/com/circle/collection/LinkedListV2Test.java new file mode 100644 index 0000000000..68ff190ed2 --- /dev/null +++ b/group03/58555264/src/test/java/com/circle/collection/LinkedListV2Test.java @@ -0,0 +1,245 @@ +package com.circle.collection; + +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by keweiyang on 2017/3/14. + */ +public class LinkedListV2Test { + + private LinkedListV2 list = new LinkedListV2(); + + @Test + public void add() throws Exception { + list.add(null); + list.add(1); + list.add(2); + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + } + + @Test + public void add1() throws Exception { + list.add(0, 1); + list.add(1, 3); + list.add(2, 5); + list.add(6); + + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + + + } + + @Test + public void get() throws Exception { + list.add(0, 1); + list.add(1, 3); + list.add(2, 5); + list.add(6); + Assert.assertEquals(6, list.get(2)); + + } + + @Test + public void size() throws Exception { + list.add(0, 1); + list.add(1, 3); + list.add(2, 5); + list.add(6); + Assert.assertEquals(4, list.size()); + + } + + @Test + public void removeFirst() throws Exception { + list.add(0, 1); + list.add(1, 3); + list.add(2, 5); + list.add(6); + + Assert.assertEquals(1, list.removeFirst()); + + } + + @Test + public void removeLast() throws Exception { + list.add(0, 1); + list.add(1, 3); + list.add(2, 5); + list.add(6); + + Assert.assertEquals(6,list.removeLast()); + + } + + @Test + public void reverse() throws Exception { + list.add(0, 3); + list.add(1, 7); + list.add(2, 10); + + list.reverse(); + + } + + @Test + public void removeFirstHalf() throws Exception { + list.add(0, 2); + list.add(1, 5); + list.add(2, 7); + list.add(3, 8); + list.add(4, 10); + list.removeFirstHalf(); + + } + + @Test + public void remove() throws Exception { + list.add(0, 2); + list.add(1, 5); + list.add(2, 7); + list.add(3, 8); + list.add(4, 10); + list.remove(2, 3); + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + + } + + @Test + public void getElements() throws Exception { + list.add(0, 11); + list.add(1, 101); + list.add(2, 201); + list.add(3, 301); + list.add(4, 401); + list.add(5, 501); + list.add(6, 601); + + LinkedListV2 listV2 = new LinkedListV2(); + listV2.add(0, 1); + listV2.add(1, 3); + listV2.add(2, 4); + listV2.add(3, 6); + + Object[] results = list.getElements(listV2); + System.out.println(results.length); + + assertEquals(4, results.length); + + for (Object object : results) { + System.out.println(object); + + } + + } + + @Test + public void toArray() throws Exception { + + } + + @Test + public void subtract() throws Exception { + list.add(0, 100); + list.add(1, 101); + list.add(2, 201); + list.add(3, 301); + list.add(4, 401); + list.add(5, 501); + list.add(6, 601); + + LinkedListV2 listV2 = new LinkedListV2(); + listV2.add(0, 100); + listV2.add(1, 301); + listV2.add(2, 401); + listV2.add(3, 601); + list.subtract(listV2); + + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + + + } + + @Test + public void removeDuplicateValues() throws Exception { + + list.add(0, 100); + list.add(1, 100); + list.add(2, 201); + list.add(3, 301); + list.add(4, 401); + list.add(5, 401); + list.add(6, 401); + list.removeDuplicateValues(); + + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + } + + @Test + public void removeRange() throws Exception { + + list.add(0, 100); + list.add(1, 110); + list.add(2, 201); + list.add(3, 211); + list.add(4, 151); + list.add(5, 131); + list.add(6, 171); + list.removeRange(110, 150); + + Iterator it = list.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + + } + + @Test + public void intersection() throws Exception { + list.add(0, 100); + list.add(1, 110); + list.add(2, 201); + list.add(3, 211); + list.add(4, 351); + list.add(5, 431); + + LinkedListV2 listV2 = new LinkedListV2(); + listV2.add(0, 100); + listV2.add(1, 351); + listV2.add(2, 431); + listV2.add(3, 600); + + LinkedListV2 integerLinkedListV2 = list.intersection(listV2); + + Iterator it = integerLinkedListV2.iterator(); + while (it.hasNext()) { + System.out.println(it.next()); + + } + } + + +} \ No newline at end of file diff --git a/group03/58555264/src/test/java/com/circle/download/FileDownloaderTest.java b/group03/58555264/src/test/java/com/circle/download/FileDownloaderTest.java new file mode 100644 index 0000000000..e22edd2ba9 --- /dev/null +++ b/group03/58555264/src/test/java/com/circle/download/FileDownloaderTest.java @@ -0,0 +1,49 @@ +package com.circle.download; + +import com.circle.download.api.ConnectionManager; +import com.circle.download.api.DownloadListener; +import com.circle.download.impl.ConnectionManagerFactory; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.*; + +/** + * Created by keweiyang on 2017/3/13. + */ +public class FileDownloaderTest { + + private boolean downloadFinished = false; + private int threadNum = 3; + + + @Test + public void execute() throws Exception { + String url = "http://hiphotos.baidu.com/240728057/pic/item/6a50e38242aad8f60cf4d2b3.jpg"; + FileDownloader downloader = new FileDownloader(url, threadNum); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + + } + }); + + downloader.execute(); + + + while (!downloadFinished) { + System.out.println("还没有下载完成,休眠5秒"); + + Thread.sleep(5000); + + } + + System.out.println("下载完成!"); + + + } + +} \ No newline at end of file diff --git a/group03/619224754/src/com/coderising/lru/LRU.java b/group03/619224754/src/com/coderising/lru/LRU.java new file mode 100644 index 0000000000..358646e087 --- /dev/null +++ b/group03/619224754/src/com/coderising/lru/LRU.java @@ -0,0 +1,75 @@ +package com.coderising.lru; + +public class LRU { + private static final int N = 5; + Object[] arr = new Object[N]; + + private int size; + + public boolean isEmpty() { + if(size == 0) { + return true; + } + else { + return false; + } + } + + public boolean isOutOfBoundary() { + if(size >= N) { + return true; + } + else { + return false; + } + } + + public int indexOfElement(Object o) { + for(int i = 0; i < size; i++){ + if(o == arr[i]) { + return i; + } + } + return -1; + } + + public Object push(Object o) { + Object popObject = null; + if(!isOutOfBoundary() && indexOfElement(o) == -1) { + arr[size] = o; + size++; + } + else if(isOutOfBoundary() && indexOfElement(o) == -1) { + popObject = arr[0]; + System.arraycopy(arr, 1, arr, 0, size -1); + arr[size - 1] = o; + } + else { + int index = indexOfElement(o); + System.arraycopy(arr, index + 1, arr, index, size - index - 1); + arr[size -1] = o; + } + + return popObject; + } + + public void showMemoryBlock() { + for(int i=0; i 0) { + for(int i = 0; i < size; i++) { + retStr += "," + arr[i]; + } + retStr = retStr.substring(1); + } + return retStr; + + } + +} diff --git a/group03/619224754/src/com/coding/basic/Dequeue.java b/group03/619224754/src/com/coding/basic/Dequeue.java new file mode 100644 index 0000000000..d80a07838a --- /dev/null +++ b/group03/619224754/src/com/coding/basic/Dequeue.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class Dequeue { + private int size = 0; + private LinkedList list = new LinkedList(); + + public void enHeadQueue(Object o){ + list.addFirst(o); + } + + public Object deHeadQueue(){ + Object ret = list.removeFirst(); + return ret; + } + + public void enLastQueue(Object o){ + list.addLast(o); + } + + public Object deLastQueue(){ + Object ret = list.removeLast(); + return ret; + } + + public boolean isEmpty(){ + return list.size() == 0; + } + + public int size(){ + return list.size(); + } +} diff --git a/group03/619224754/src/test/LRUTest.java b/group03/619224754/src/test/LRUTest.java new file mode 100644 index 0000000000..c777482e38 --- /dev/null +++ b/group03/619224754/src/test/LRUTest.java @@ -0,0 +1,23 @@ +package test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.coderising.lru.LRU; + +public class LRUTest { + + @Test + public void test() { + + Integer iter[] = {4,7,0,7,1,0,1,2,1,2,6}; + LRU lru = new LRU(); + for(int i=0; i - - + - - - - + + + - - + diff --git a/group03/664269713/DataStructure/src/com/ace/coding/LinkedList.java b/group03/664269713/DataStructure/src/com/ace/coding/LinkedList.java index 351a6a8277..fc26d882ee 100644 --- a/group03/664269713/DataStructure/src/com/ace/coding/LinkedList.java +++ b/group03/664269713/DataStructure/src/com/ace/coding/LinkedList.java @@ -1,123 +1,315 @@ -package com.ace.coding; - -public class LinkedList implements List { - private Node head = null; - private int size = 0; - - public void add(Object o){ - Node newNode = new Node(); - newNode.data = o; - if(head == null){ - head = newNode; - } else { - Node pNode = head; - while(pNode.next != null){ - pNode = pNode.next; - } - pNode.next = newNode; - } - size++; - } - - public void add(int index , Object o){ - checkLinkedListIndex(index); - - Node newNode = new Node(); - newNode.data = o; - Node pNode = getNode(index); - newNode.next = pNode.next; - pNode.next = newNode; - - size++; - } - - private Node getNode(int index){ - Node pNode = head; - for(int i = 0; i < index; i++){ - pNode = pNode.next; - } - return pNode; - } - - public Object get(int index){ - Node pNode = getNode(index); - return pNode.data; - } - public Object remove(int index){ - checkLinkedListIndex(index); - - Node pNode = head; - for(int i = 0; i < index - 1; i++){ - pNode = pNode.next; - } - Node tempNode = getNode(index); - pNode.next = tempNode.next; - size--; - return tempNode.data; - } - - - public void addFirst(Object o){ - Node newNode = new Node(); - newNode.data = o; - newNode.next = head; - head = newNode; - size++; - } - public void addLast(Object o){ - Node newNode = new Node(); - newNode.data = o; - Node pNode = getNode(size() - 1); - pNode.next = newNode; - size++; - } - public Object removeFirst(){ - Node pNode = head; - head = pNode.next; - size--; - return pNode.data; - } - public Object removeLast(){ - Object obj = remove(size() - 1); - return obj; - } - - public int size(){ - return size; - } - - private void checkLinkedListIndex(int index){ - if(index < 0 || index >= size()){ - throw new IndexOutOfBoundsException("The index " + index + " is invalid."); - } - } - - public Iterator iterator(){ - return null; -// return new ListIterator(); - } - - /*private class ListIterator implements Iterator{ - private Node pNode = head; - - @Override - public boolean hasNext() { - // TODO Auto-generated method stub - return pNode.next != null; - } - - @Override - public Object next() { - // TODO Auto-generated method stub - Object obj = pNode.data; - pNode = pNode.next; - return obj; - } - - }*/ - - private static class Node{ - Object data; - Node next; - } -} +package com.ace.coding; + +import java.lang.reflect.Array; + +public class LinkedList implements List { + private Node head = null; + private int size = 0; + + public void add(Object o){ + Node newNode = new Node(); + newNode.data = o; + if(head == null){ + head = newNode; + } else { + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + } + pNode.next = newNode; + } + size++; + } + + public void add(int index , Object o){ + checkLinkedListIndex(index); + + Node newNode = new Node(); + newNode.data = o; + Node pNode = getNode(index); + newNode.next = pNode.next; + pNode.next = newNode; + + size++; + } + + private Node getNode(int index){ + Node pNode = head; + for(int i = 0; i < index; i++){ + pNode = pNode.next; + } + return pNode; + } + + public Object get(int index){ + Node pNode = getNode(index); + return pNode.data; + } + public Object remove(int index){ + checkLinkedListIndex(index); + if(index == 0){ + return removeFirst(); + } + + Node pNode = head; + for(int i = 0; i < index - 1; i++){ + pNode = pNode.next; + } + Node tempNode = getNode(index); + pNode.next = tempNode.next; + size--; + return tempNode.data; + } + + + public void addFirst(Object o){ + Node newNode = new Node(); + newNode.data = o; + newNode.next = head; + head = newNode; + size++; + } + public void addLast(Object o){ + Node newNode = new Node(); + newNode.data = o; + Node pNode = getNode(size() - 1); + pNode.next = newNode; + size++; + } + public Object removeFirst(){ + Node pNode = head; + head = pNode.next; + size--; + return pNode.data; + } + public Object removeLast(){ + Object obj = remove(size() - 1); + return obj; + } + + public int size(){ + return size; + } + + private void checkLinkedListIndex(int index){ + if(index < 0 || index >= size()){ + throw new IndexOutOfBoundsException("The index " + index + " is invalid."); + } + } + + public Iterator iterator(){ + return null; +// return new ListIterator(); + } + + /*private class ListIterator implements Iterator{ + private Node pNode = head; + + @Override + public boolean hasNext() { + // TODO Auto-generated method stub + return pNode.next != null; + } + + @Override + public Object next() { + // TODO Auto-generated method stub + Object obj = pNode.data; + pNode = pNode.next; + return obj; + } + + }*/ + + private static class Node{ + Object data; + Node next; + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Node headNode = head; + Node newNode = null; + + reverseNode(headNode, newNode); + } + + private void reverseNode(Node headNode, Node newHead){ + if(headNode != null){ + return ; + } + + Node next = headNode.next; + headNode.next = newHead; + + if(next == null){ + return ; + } + + reverseNode(next, headNode); + } + + private void checkLinkedListSize(){ + if(this.size() <= 0){ + throw new IndexOutOfBoundsException(); + } + } + + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + //check empty + checkLinkedListSize(); + int count = 1; + Node pNode = head; + for (int i = 0; i < size() / 2 - 1; i++) { + pNode = pNode.next; + count++; + } + head = pNode.next; + size = size() - count; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + //check empty + // check i and length are validate + checkLinkedListSize(); + checkLinkedListIndex(i); + checkLinkedListIndex(i+length); + + if(i == 0){ + Node pNode = getNode(length - 1); + head = pNode.next; + } else { + Node pNode = getNode(i - 1); + Node tempNode = getNode(i + length - 1); + pNode.next = tempNode.next; + } + size = size - length; + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] newArray = new int[list.size()]; + ArrayList newArrayList = new ArrayList(); + for(int i = 0; i < list.size(); i++){ + newArray[i] = (int)this.get((int)list.get(i)); + } + + return newArray; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * @param list + */ + + public void subtract(LinkedList list){ + ArrayList arrayList = new ArrayList(); + for(int i = 0; i < this.size(); i++){ + for(int j = 0; j < list.size(); j++){ + if(this.get(i) == list.get(j)){ + arrayList.add(i); + break; + } + } + } + + for(int k = 0; k < arrayList.size(); k++){ + this.remove((int)arrayList.get(k) - k); + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + ArrayList arrayList = new ArrayList(); + for(int i = 0; i < this.size() - 1; i++){ + if(this.get(i) == this.get(i+1)){ + arrayList.add(i); + } + } + + for(int k = 0; k < arrayList.size(); k++){ + this.remove((int)arrayList.get(k) - k); + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + ArrayList newArrayList = new ArrayList(); + int count = 0; + int start = 0; + int end = 0; + for (int i = 0; i < this.size(); i++) { + if(min >= (int)this.get(i)){ + start = i+1; + } + if(max >= (int)this.get(i)){ + end = i; + } + } + this.remove(start, end-start); + } + + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList newLinkedList = new LinkedList(); + int l1 = 0; + int l2 = 0; + while(l1 < this.size() && l2 < list.size()){ + if(this.get(l1) == list.get(l2)){ + newLinkedList.add(this.get(l1)); + l1 ++; + l2 ++; + } else if ((int)this.get(l1) > (int)list.get(l2)){ + l1 ++; + } else { + l2 ++; + } + } + + return newLinkedList; + } + + private boolean contains(Object obj){ + for(int i = 0; i < this.size(); i++){ + if(this.get(i) == obj){ + return true; + } + } + return false; + } + +} diff --git a/group03/664269713/DataStructure/src/com/ace/coding/LinkedListTest.java b/group03/664269713/DataStructure/src/com/ace/coding/LinkedListTest.java new file mode 100644 index 0000000000..913a8e222c --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/coding/LinkedListTest.java @@ -0,0 +1,33 @@ +package com.ace.coding; + +/** + * Created by ace on 2017/3/11. + */ +public class LinkedListTest { + public static void showLinkedList(LinkedList linkedList){ + for (int i = 0; i < linkedList.size(); i++){ + System.out.println(linkedList.get(i)); + } + } + public static void main(String[] args){ + LinkedList linkedList = new LinkedList(); + linkedList.add(2); + linkedList.add(3); + linkedList.add(3); + linkedList.add(3); + linkedList.add(10); + + LinkedList numberLink = new LinkedList(); + numberLink.add(2); + numberLink.add(3); + numberLink.add(5); + + /*int[] newArray = linkedList.getElements(numberLink); + for (int i = 0; i < newArray.length; i++) { + System.out.println(newArray[i]); + }*/ + numberLink.reverse(); +// linkedList.removeRange(3,8); + showLinkedList(numberLink); + } +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/DownloadThread.java b/group03/664269713/DataStructure/src/com/ace/download/DownloadThread.java new file mode 100644 index 0000000000..cbba41791b --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/DownloadThread.java @@ -0,0 +1,46 @@ +package com.ace.download; + +import com.ace.download.api.Connection; +import com.ace.download.api.DownloadListener; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class DownloadThread extends Thread{ + + private Connection conn; + private int startPos; + private int endPos; + CyclicBarrier barrier; + String filePath; + + 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 { + byte[] bytes = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile(filePath, "rwd"); + raf.seek(startPos); + raf.write(bytes); + raf.close(); + conn.close(); + barrier.await(); + + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + } +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/FileDownloader.java b/group03/664269713/DataStructure/src/com/ace/download/FileDownloader.java new file mode 100644 index 0000000000..edf3cf6a22 --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/FileDownloader.java @@ -0,0 +1,99 @@ +package com.ace.download; + + +import com.ace.download.api.Connection; +import com.ace.download.api.ConnectionException; +import com.ace.download.api.ConnectionManager; +import com.ace.download.api.DownloadListener; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + String filePath; + + + public FileDownloader(String _url, String filePath) { + this.url = _url; + this.filePath = filePath; + } + + private String generateFileName(String url){ + String fileName = url.substring(url.lastIndexOf("/")); + return fileName; + } + + 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(3 , new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }); + + Connection conn = null; + try { + + RandomAccessFile raf = new RandomAccessFile(filePath, "rwd"); + + conn = cm.open(this.url); + raf.setLength(conn.getContentLength()); + + int length = conn.getContentLength(); + int partSize = (length % 3 == 0) ? length / 3 : (length / 3 + 1); + + for(int i = 0; i < 3; i++) { + int startPos = partSize * i; + int endPos = partSize * (i + 1) - 1; + new DownloadThread(conn, startPos, endPos, filePath, barrier).start(); + } + + } catch (ConnectionException 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/group03/664269713/DataStructure/src/com/ace/download/api/Connection.java b/group03/664269713/DataStructure/src/com/ace/download/api/Connection.java new file mode 100644 index 0000000000..2286c0133d --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.ace.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() throws IOException; + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/api/ConnectionException.java b/group03/664269713/DataStructure/src/com/ace/download/api/ConnectionException.java new file mode 100644 index 0000000000..11120a8fc5 --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.ace.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/api/ConnectionManager.java b/group03/664269713/DataStructure/src/com/ace/download/api/ConnectionManager.java new file mode 100644 index 0000000000..24b8d53204 --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/api/ConnectionManager.java @@ -0,0 +1,13 @@ +package com.ace.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; +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/api/DownloadListener.java b/group03/664269713/DataStructure/src/com/ace/download/api/DownloadListener.java new file mode 100644 index 0000000000..f55e21d241 --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.ace.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionImpl.java b/group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..273da2a995 --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionImpl.java @@ -0,0 +1,57 @@ +package com.ace.download.impl; + +import com.ace.download.api.Connection; +import com.ace.download.api.ConnectionManager; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URLConnection; +import java.util.Arrays; + + +public class ConnectionImpl implements Connection { + private URL urlObj; + private InputStream inputStream; + private ByteArrayOutputStream byteArrayOutputStream; + + public ConnectionImpl(URL urlObj){ + this.urlObj = urlObj; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + URLConnection urlConnection = urlObj.openConnection(); + urlConnection.setRequestProperty("Range","bytes=" + startPos + "-" + endPos); + inputStream = urlConnection.getInputStream(); + byteArrayOutputStream = new ByteArrayOutputStream(); + + byte[] bytes = new byte[1024]; + int length = 0; + while((length = inputStream.read(bytes)) != -1){ + byteArrayOutputStream.write(bytes, 0, length); + } + byte[] data = byteArrayOutputStream.toByteArray(); + int contentLen = endPos - startPos + 1; + if(byteArrayOutputStream.size() > contentLen){ + data = Arrays.copyOf(data, contentLen); + } + + return data; + } + + @Override + public int getContentLength() throws IOException { + URLConnection urlConnection = urlObj.openConnection(); + return urlConnection.getContentLength(); + } + + @Override + public void close() { + + } + +} diff --git a/group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionManagerImpl.java b/group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..b5f37acbc6 --- /dev/null +++ b/group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,28 @@ +package com.ace.download.impl; + + +import com.ace.download.api.Connection; +import com.ace.download.api.ConnectionException; +import com.ace.download.api.ConnectionManager; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + private URL urlObj; + private Connection connection; + + @Override + public Connection open(String url) { + try { + urlObj = new URL(url); + connection = new ConnectionImpl(urlObj); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + + return connection; + } + +} diff --git a/group03/664269713/DataStructure/src/com/ace/homework2/Struts.java b/group03/664269713/DataStructure/src/com/ace/homework2/Struts.java index 175ce8a10c..e2db085b2b 100644 --- a/group03/664269713/DataStructure/src/com/ace/homework2/Struts.java +++ b/group03/664269713/DataStructure/src/com/ace/homework2/Struts.java @@ -10,25 +10,21 @@ import java.util.List; import java.util.Map; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.Element; -import org.dom4j.io.SAXReader; public class Struts { /* - * 0. ȡļstruts.xml + * 0. ��ȡ�����ļ�struts.xml * - * 1. actionNameҵӦclass LoginAction, ͨʵ - * parametersеݣösetter parametersе ("name"="test" , - * "password"="1234") , ǾӦõ setNamesetPassword + * 1. ����actionName�ҵ����Ӧ��class �� ����LoginAction, ͨ������ʵ�������������� + * ��parameters�е����ݣ����ö����setter������ ����parameters�е������� ("name"="test" , + * "password"="1234") , �Ǿ�Ӧ�õ��� setName��setPassword���� * - * 2. ͨöexectue ÷ֵ"success" + * 2. ͨ��������ö����exectue ������ ����÷���ֵ������"success" * - * 3. ͨҵgetter getMessage, ͨã ֵγһHashMap , - * {"message": "¼ɹ"} , ŵViewparameters + * 3. ͨ�������ҵ����������getter���������� getMessage��, ͨ�����������ã� ��ֵ�������γ�һ��HashMap , ���� + * {"message": "��¼�ɹ�"} , �ŵ�View�����parameters * - * 4. struts.xmlе ,Լexecuteķֵ ȷһjsp ŵViewjspֶС + * 4. ����struts.xml�е� ����,�Լ�execute�ķ���ֵ�� ȷ����һ��jsp�� �ŵ�View�����jsp�ֶ��С� */ private static final String STRUTS_XML = "struts.xml"; private static final String NAME = "name"; @@ -38,7 +34,7 @@ public class Struts { private static final String SET = "set"; private static List getStrutsList() { - List strutsObjList = new ArrayList(); + /*List strutsObjList = new ArrayList(); URL path = Struts.class.getResource(STRUTS_XML); File f = new File(path.getFile()); SAXReader saxReader = new SAXReader(); @@ -66,7 +62,8 @@ private static List getStrutsList() { e.printStackTrace(); } - return strutsObjList; + return strutsObjList;*/ + return null; }; public static View runAction(String actionName, Map parameters) { diff --git a/group06/1378560653/.classpath b/group06/1378560653/.classpath index 3e0fb272a8..036cc56d25 100644 --- a/group06/1378560653/.classpath +++ b/group06/1378560653/.classpath @@ -3,5 +3,6 @@ + diff --git a/group06/1378560653/article.txt b/group06/1378560653/article.txt index 478dde01b7..42b64998ea 100644 --- a/group06/1378560653/article.txt +++ b/group06/1378560653/article.txt @@ -1,3 +1,5 @@ һƪ£http://blog.csdn.net/raymond120/article/details/57415472 ڶƪ£http://blog.csdn.net/raymond120/article/details/58043040 -ƪ£http://blog.csdn.net/raymond120/article/details/60759278 \ No newline at end of file +ƪ£http://blog.csdn.net/raymond120/article/details/60759278 +ƪ£http://blog.csdn.net/raymond120/article/details/61937892 +ƪ£http://blog.csdn.net/raymond120/article/details/68665071 \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/array/ArrayUtil.java b/group06/1378560653/src/com/coderising/array/ArrayUtil.java deleted file mode 100644 index 2542d4336d..0000000000 --- a/group06/1378560653/src/com/coderising/array/ArrayUtil.java +++ /dev/null @@ -1,212 +0,0 @@ -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){ - //一定要判断边界条件 - if(origin == null || origin.length == 0){ - return; - } - int N = origin.length; - for(int i = 0; i < N/2; i++){ - int temp = origin[i]; - origin[i] = origin[N-i-1]; - origin[N-i-1] = 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 int[] removeZero(int[] oldArray){ - int N = oldArray.length; - int[] newArray = new int[N]; - int j = 0; - for(int i = 0; i < N; i++){ - if(oldArray[i] != 0){ - newArray[j] = oldArray[i]; - j++; - } - } - return newArray; - } - - /** - * 给定两个已经排序好的整形数组, 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){ - int N = array1.length + array2.length; - int[] array3 = new int[N]; - System.arraycopy(array1, 0, array3, 0, array1.length); - for(int i = 0; i < N; i++){ - for(int j = 0; j < array2.length; j++){ - if(array3[i] > array2[j]){ - System.arraycopy(array3, i , array3, i+1, N-i-1); - array3[i] = array2[j]; - } - } - } - return array3; - } - /** - * 把一个已经存满数据的数组 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){ - int[] newArray = new int[oldArray.length + size]; - System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); - 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 int[] fibonacci(int max){ - int[] zero = new int[0]; - int[] array = new int[100]; - array[0] = 1; - array[1] = 1; - int i = 1; - - if(max == 1){ - return zero; - }else{ - while(array[i] <= max){ - i++; - if(i > array.length){ - grow(array, i*2); - } - array[i+1] = array[i] + array[i-1]; - } - return array; - } - } - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public int[] getPrimes(int max){ - boolean[] prime = new boolean[max + 1]; - int[] zero = new int[0]; - int[] array = new int[max]; - int q = 1; - if(max == 1 || max ==2){ - return zero; - }else{ - for(int i = 3; i < max; i++) - if(i % 2 == 0){ - prime[i] = false; - }else{ - prime[i] = true; - } - - for(int i = 3; i < Math.sqrt(max); i++){//因子;若n是合数,则其所有因子都不超过sqrt(n) - if(prime[i]) - for(int j = 2 * i; j<= max; j += i){//其倍数 - prime[j] = false; - } - } - array[0] = 2; - for(int p = 0; p < max; p++){ - if(prime[p] == true){ - array[q] = p; - q++; - } - } - return array; - } - } - /*int[] zero = new int[0]; - int[] array = new int[100]; - int k = 0; - - if(max == 1 || max == 2){ - return zero; - }else{ - for(int n = 2; n <= max; n++){ - int isPrime = 1; - for(int i = 2; i < n; i++){ - if(n % i == 0){ - isPrime = 0; - break; - } - if(isPrime == 1){ - array[k] = n; - k++; - } - } - } - return array; - }*/ - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * @param max - * @return - */ - public int[] getPerfectNumbers(int max){ - int[] perfectNumbers = new int[max]; - int n = 0; - for(int i = 1; i < max; i++){//i:要判断的数 - int sum = 0; - for(int j = 1; j < i; j++){//j:可能因子 - if(i % j == 0){ - sum += j; - } - } - if(sum == i){ - perfectNumbers[n] = i; - n++; - } - } - return perfectNumbers; - } - - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" - * @param array - * @param s - * @return - */ - public String join(int[] array, String seperator){ - String s = ""; - for(int i = 0; i < array.length; i++){ - s = s + array[i] + seperator; - } - return s; - } - - -} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/download/DownloadThread.java b/group06/1378560653/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..fd0fc27001 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,40 @@ +package com.coderising.download; + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String localFile; + CyclicBarrier barrier; + + public DownloadThread( Connection conn, int startPos, int endPos, String localFile, CyclicBarrier barrier){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + + public void run(){ + + try { + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + file.seek(startPos); + file.write(data); + file.close(); + conn.close(); + barrier.await();//等待别的线程完成 + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/download/FileDownloader.java b/group06/1378560653/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..5a260a365b --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,131 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; +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 static final int DOWNLOAD_THREAD_NUM = 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类的用法: + * 当多个线程需要互相等待,直到所有线程跨过某个“屏障”的时候,用这个类 + */ + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM, new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }) ; + + Connection conn = null; + + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + createPlaceHolderFile(this.localFile, length); //占位子 + + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length);//分配每个线程的下载长度 + + for(int i = 0; i < DOWNLOAD_THREAD_NUM;i++){ + + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + thread.start(); + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + } + + private int[][] allocateDownloadRange(int threadNum, int contentLen) { + int[][] ranges = new int[threadNum][2]; + + int eachThreadSize = contentLen / threadNum; + int left = contentLen % threadNum; + + for(int i = 0; i < threadNum; i++){ + int startPos = i * threadNum; + + int endPos = (i + 1) * eachThreadSize - 1; + + if((i == (threadNum - 1))){ + endPos += left; + } + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + return ranges; + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + + RandomAccessFile file = new RandomAccessFile(fileName, "rw");//以读写方式 + + for(int i = 0; i < contentLen; 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; + } + +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/download/api/Connection.java b/group06/1378560653/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group06/1378560653/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/group06/1378560653/src/com/coderising/download/api/ConnectionException.java b/group06/1378560653/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..505f61e224 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,9 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(Exception e) { + super(e); + } + +} diff --git a/group06/1378560653/src/com/coderising/download/api/ConnectionManager.java b/group06/1378560653/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..0a625bf472 --- /dev/null +++ b/group06/1378560653/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; //得到一个Connection的实例 +} diff --git a/group06/1378560653/src/com/coderising/download/api/DownloadListener.java b/group06/1378560653/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group06/1378560653/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/group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java b/group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..643984ee73 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,96 @@ +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; + + +//非public class,仅包内可见,依靠ConnectionMangerImpl实现 +class ConnectionImpl implements Connection { + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException { + try { + this.url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + /* + * 分段读取数据 + * @see com.coderising.download.api.Connection#read(int, int) + */ + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + /* + * HttpURLConnection是基于HTTP协议的,HttpURLConnection的对象不能直接构造,需要通过url.openConnection()来获得HttpURLConnection对象 + * 示例如下: + * String slurl = "http://...."; + * URL url = new URL(slurl); + * HttpURLConnection httpCoon = (HttpURLConnection) url.openConnection(); + * 调用HttpURLConnection连接对象的getInputStream()函数,将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端 + */ + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + httpConn.setRequestProperty("Range","bytes=" + startPos + "-" + endPos); //只发一个特定的片段,比is.skip有效 + InputStream is = httpConn.getInputStream();// 注意,实际发送请求的代码段就在这里 -------------------------------输入流 + + //is.skip(startPos);//跳过startPos之前的内容 + + byte[] buff = new byte[BUFFER_SIZE]; + int totalLen = endPos - startPos + 1; //注意+1 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节数组流, 可以捕获内存缓冲区的数据,转换成字节数组。----输出流 + + while(baos.size() < totalLen){ + + int len = is.read(buff);//从输入流中读取数据到buff数组,同时返回读取长度,每次读取量小于等于1024 + if (len < 0){ + break; + } + baos.write(buff, 0, len);//buff数组中的数据写入输出流 + } + + if(baos.size() > totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + + /* + * 获取资源长度 + * @see com.coderising.download.api.Connection#getContentLength() + */ + @Override + public int getContentLength() { + URLConnection con; + try { + con = url.openConnection(); + + return con.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + + return -1; + } + + @Override + public void close() { + + + } + +} diff --git a/group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..bdd7d3f8e9 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java b/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..ff832c8dde --- /dev/null +++ b/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,61 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + String classDirName = className.replace('.', '\\')+".class"; + String clzpath = getClassPath()+"\\"+ classDirName; + try { + FileInputStream clz = new FileInputStream(clzpath); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int flag = 0; + while((flag = clz.read())!=-1){ + baos.write(flag); + } + clz.close(); + return baos.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + + public void addClassPath(String path) { + File file = new File(path); + if(file.exists()){ + clzPaths.add(path); + } else { + throw new IllegalArgumentException("路径:"+path+"不存在"); + } + } + + + public String getClassPath(){ + if(clzPaths.isEmpty()){ + return " "; + } + + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < clzPaths.size(); i++) { + buf.append(clzPaths.get(i)); + if(i != (clzPaths.size() - 1)){ + buf.append(";"); + } + } + return buf.toString(); + } + +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..3ace0974f5 --- /dev/null +++ b/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,85 @@ +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 = "H:\\github\\coding2017\\group06\\1378560653\\bin"; + 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 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/group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java b/group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..97e286827f --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +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/group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java b/group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..734649f37a --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.coderising.litestruts; + +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/group06/1378560653/src/com/coderising/litestruts/LoginAction.java b/group06/1378560653/src/com/coderising/litestruts/LoginAction.java index 76547ac3b3..52a9b71cfb 100644 --- a/group06/1378560653/src/com/coderising/litestruts/LoginAction.java +++ b/group06/1378560653/src/com/coderising/litestruts/LoginAction.java @@ -2,7 +2,7 @@ /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @author liuxin + * @author * */ public class LoginAction{ @@ -36,4 +36,4 @@ public void setPassword(String password){ public String getMessage(){ return this.message; } -} \ No newline at end of file +} diff --git a/group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..dda2eec6dd --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.coderising.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; + +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 getParameterMap(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/group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..af378808c6 --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,111 @@ +package com.coderising.litestruts; + +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 testGetParameters() 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.getParameterMap(action); + + Assert.assertEquals(3, params.size()); + + + Assert.assertEquals(null, params.get("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + } + +} diff --git a/group06/1378560653/src/com/coderising/litestruts/Struts.java b/group06/1378560653/src/com/coderising/litestruts/Struts.java index 0e73017f99..885c604940 100644 --- a/group06/1378560653/src/com/coderising/litestruts/Struts.java +++ b/group06/1378560653/src/com/coderising/litestruts/Struts.java @@ -1,31 +1,26 @@ package com.coderising.litestruts; -import java.io.IOException; +import java.lang.reflect.Method; import java.util.Map; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; 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,通过反射实例化(创建对象) + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , "password"="1234") , 那就应该调用 setName和setPassword方法 - 2. 通过反射调用对象的exectue方法, 并获得返回值,例如"success" + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , @@ -35,22 +30,37 @@ public static View runAction(String actionName, Map parameters) { 放到View对象的jsp字段中。 */ + + String clzName = cfg.getClassName(actionName); + + if(clzName == null){ + return null; + } - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse("structs.xml"); - NodeList actionList = document.getElementsByTagName("action"); + + 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.getParameterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + + + + } catch (Exception e) {//得处理这个异常 - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { e.printStackTrace(); } - return null; } -} \ No newline at end of file +} diff --git a/group06/1378560653/src/com/coderising/litestruts/StructsTest.java b/group06/1378560653/src/com/coderising/litestruts/StrutsTest.java similarity index 97% rename from group06/1378560653/src/com/coderising/litestruts/StructsTest.java rename to group06/1378560653/src/com/coderising/litestruts/StrutsTest.java index 4e761b0b2d..a44021cacc 100644 --- a/group06/1378560653/src/com/coderising/litestruts/StructsTest.java +++ b/group06/1378560653/src/com/coderising/litestruts/StrutsTest.java @@ -7,7 +7,7 @@ import org.junit.Test; -public class StructsTest { +public class StrutsTest { @Test public void testLoginActionSuccess() { @@ -37,4 +37,4 @@ public void testLoginActionFailed() { Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); } -} \ No newline at end of file +} diff --git a/group06/1378560653/src/com/coderising/litestruts/struts.xml b/group06/1378560653/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..e5d9aebba8 --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/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/group06/1378560653/src/com/coding/basic/Queue.java b/group06/1378560653/src/com/coding/basic/Queue.java index a574f4b859..7a82835913 100644 --- a/group06/1378560653/src/com/coding/basic/Queue.java +++ b/group06/1378560653/src/com/coding/basic/Queue.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coding.basic.linklist.LinkedList; + public class Queue { private LinkedList linkedlist = new LinkedList(); diff --git a/group06/1378560653/src/com/coding/basic/Stack.java b/group06/1378560653/src/com/coding/basic/Stack.java index 2d0b260880..37fb5f26b5 100644 --- a/group06/1378560653/src/com/coding/basic/Stack.java +++ b/group06/1378560653/src/com/coding/basic/Stack.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coding.basic.array.ArrayList; + public class Stack { private ArrayList elementData = new ArrayList(); diff --git a/group06/1378560653/src/com/coding/basic/ArrayList.java b/group06/1378560653/src/com/coding/basic/array/ArrayList.java similarity index 95% rename from group06/1378560653/src/com/coding/basic/ArrayList.java rename to group06/1378560653/src/com/coding/basic/array/ArrayList.java index 8d9d0c30fb..9fd1e776cc 100644 --- a/group06/1378560653/src/com/coding/basic/ArrayList.java +++ b/group06/1378560653/src/com/coding/basic/array/ArrayList.java @@ -1,4 +1,7 @@ -package com.coding.basic; +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import com.coding.basic.List; public class ArrayList implements List { diff --git a/group06/1378560653/src/com/coding/basic/array/ArrayUtil.java b/group06/1378560653/src/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..3e3b51e735 --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,262 @@ +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 void reverseArray(int[] origin){ + //注意边界条件 + if(origin == null || origin.length == 0){ + return; + } + + for(int i=0, j = origin.length-1; i array2[j]){ + newArray[count++] = array2[j++]; + }else if(array1[i] == array2[j]){ + newArray[count++] = array2[j++]; + i++; + } + } + + while(i==array1.length && j= max){ + break; + }else{ + count++; + } + } + + return Arrays.copyOf(a,count); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + if(max < 3){ + return new int[0]; + } + + boolean[] isPrime = isPrime(max); + + int[] array = new int[max]; + int count = 1; + array[0] = 2; + for(int i = 3; i < max; i++){ + if(isPrime[i]){ + array[count++] = i; + } + } + return Arrays.copyOf(array, count); + } + + private boolean[] isPrime(int max) { + boolean[] isPrime = new boolean[max]; + for(int i = 3; i < max; i++){ + if(i % 2 != 0 ){ + isPrime[i] = true; + }else{ + isPrime[i] = false; + } + } + + for(int i = 3; i < Math.sqrt(max); i++){ + if(isPrime[i]){ + for(int j = 2*i ; j < max; j += i){ + isPrime[j] = false; + } + } + } + return isPrime; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + if(max < 0){ + return new int[0]; + } + + int[] Array = new int[max]; + + int count = 0; + for(int n = 1; n < max; n++) + { + int sum = 0; + for(int i=1; i< n; i++) + { + if(n%i == 0) + sum += i; + } + if(sum == n) + Array[count++] = n; + } + + return Arrays.copyOf(Array, count); + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator) + { + if(array == null || array.length == 0){ + return ""; + } + + StringBuilder buffer = new StringBuilder(); + + for(int i = 0; i < array.length; i++){ + buffer.append(array[i]); + if(i < array.length - 1){ + buffer.append(seperator); + } + } + + return buffer.toString(); + } +} diff --git a/group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java b/group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java new file mode 100644 index 0000000000..0513b8e05f --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java @@ -0,0 +1,150 @@ +package com.coding.basic.array; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ArrayUtilTest { + + private ArrayUtil myArray; + + @Before + public void setUp() throws Exception{ + myArray = new ArrayUtil(); + } + + @Test + public void testReverseArray() + { + int[] a = {1, 2, 1, 3, 5, 6}; + int[] b = {6, 5, 3, 1, 2, 1}; + + myArray.reverseArray(a); + assertArrayEquals(a, b); + + int[] c = new int[0]; + myArray.reverseArray(c); + assertArrayEquals(c, new int[0]); + + } + + @Test + public void testRemoveZero() + { + int[] oldArr= {1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 1, 2, 0, 5}; + int b[] = {1, 3, 4, 5, 6, 6, 5, 4, 7, 6, 7, 1, 2, 5}; + int[] c = myArray.removeZero(oldArr); + assertArrayEquals(b, c); + + int[] d = null; + int[] e = myArray.removeZero(d); + assertNull(e); + + } + + @Test + public void testMerge() + { + int a1[] = {1, 2, 3, 4, 5}; + int b1[] = {3, 4, 5, 6, 7, 8}; + int c1[] = {1, 2, 3, 4, 5, 6, 7, 8}; + int[] newArray1 = myArray.merge(a1, b1); + assertArrayEquals(c1, newArray1); + + int a2[] = new int[0]; + int b2[] = {0, 2, 3, 6, 7, 8}; + int c2[] = {0, 2, 3, 6, 7, 8}; + int[] newArray2 = myArray.merge(a2, b2); + assertArrayEquals(c2, newArray2); + + int a3[] = {0, 2, 3, 6, 7, 8}; + int b3[] = new int[0]; + int c3[] = {0, 2, 3, 6, 7, 8}; + int[] newArray3 = myArray.merge(a3, b3); + assertArrayEquals(c3, newArray3); + + int[] a4 = null; + int[] b4 = null; + int[] newArray4 = myArray.merge(a4, b4); + assertNull(newArray4); + } + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public void testGrow() + { + int[] a = {3, 5, 7, 8, 9}; + int[] b = {3, 5, 7, 8, 9, 0, 0, 0}; + int[] newArray = myArray.grow(a, 3); + assertArrayEquals(b, newArray); + + int[] c = null; + int[] newArray1 = myArray.grow(c, 3); + assertNull(newArray1); + + // size < 0 抛出异常 + expectedEx.expect(Exception.class); + myArray.grow(a, -3);//注意这里 + } + + @Test + public void testFibonacci() + { + //max == 1时返回空数组 + int[] array1 = myArray.fibonacci(1); + int[] b = new int[0]; + assertArrayEquals(array1, b); + + + int[] array2= myArray.fibonacci(35); + int[] c = {1, 1, 2, 3, 5, 8, 13, 21, 34 }; + assertArrayEquals(c, array2); + } + + @Test + public void testGetPrimes() + { + int[] a = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 }; + int[] array1 = myArray.getPrimes(35); + assertArrayEquals(a, array1); + + //max <= 2的时候没有素数,数组为空数组 + int[] array2 = myArray.getPrimes(1); + int[] b = new int[0]; + assertArrayEquals(array2, b); + } + + @Test + public void testGetPerfectNumbers() + { + int[] array = myArray.getPerfectNumbers(10000); + int[] a = {6, 28, 496, 8128 }; + assertArrayEquals(a, array); + } + + @Test + public void testJoin() + { + int[] Array0 = {3, 5, 7, 8, 9}; + String s0 = myArray.join(Array0, "-"); + String s1 = "3-5-7-8-9"; + assertEquals(s1, s0); + + int[] Array1 = {3}; + String s2 = myArray.join(Array1, "-"); + String s3 = "3"; + assertEquals(s2, s3); + + //传递空数组时,返回空字符串 + int[] Array2 = new int[0]; + String s4 = myArray.join(Array2, "-"); + String s5 = ""; + assertEquals(s4, s5); + } +} + diff --git a/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..75f3002227 --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,154 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + } + + private int capacity;//容量 + + private Node first; // 链表头 + private Node last; // 链表尾 + + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + if(capacity == 0){ + return; + } + + Node node = new Node(pageNum); + + //填满:从后往前填满 + if(!isFull()){ + if(first == null && last == null){ + first = node; + last = node; + first.prev = null; + last.prev = null; + } else { + first.prev = node; + node.next = first; + first = node; + } + } else { + if(!isFind(pageNum)){ + first.prev = node; + node.next = first; + first = node; + last = last.prev; + last.next = null; + } else { + Node pNode = first; + if(first.pageNum == pageNum){ + return; + } + + //注意:while循环只是遍历了1~last.prev的节点 + while(pNode.next != null){ + if(pNode.pageNum == pageNum){ + pNode.next.prev = pNode.prev; + pNode.prev.next = pNode.next; + pNode.next = first; + first.prev = pNode; + first = pNode; + break; + } + pNode = pNode.next; + } + + if(last.pageNum == pageNum){ + last.next = first; + first.prev = last; + first = last; + last = last.prev; + last.next = null; + } + } + } + + } + + private boolean isFind(int pageNum) { + Node pNode = first; + while(pNode != null){ + if(pNode.pageNum == pageNum){ + return true; + } + pNode = pNode.next; + } + return false; + } + + public boolean isFull() { + int count = 0; + Node pNode = first; + while(pNode != null){ + count++; + pNode = pNode.next; + } + + if(count < capacity){ + return false; + } else { + return true; + } + } + + + + 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(); + } + + public static void main(String args[]){ + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + System.out.println(frame.toString()); + frame.access(2); + System.out.println(frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + frame.access(3); + System.out.println(frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + frame.access(4); + System.out.println(frame.toString()); + } +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..c323d03b3f --- /dev/null +++ b/group06/1378560653/src/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()); + } + +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coding/basic/linklist/LinkedList.java b/group06/1378560653/src/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..22ad1d6070 --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,445 @@ +package com.coding.basic.linklist; + +import java.util.Arrays; +import java.util.Stack; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class LinkedList implements List { + private Node head; + private int size; + + public LinkedList(){ + this.head = null; + this.size = 0; + } + + private static class Node { + Object data; + Node next; + + private Node(Object data){ + this.data = data; + this.next = null; + } + } + + public void add(Object o){ + Node node = new Node(o); + if(head == null){ + head = node; + }else{ + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + } + pNode.next = node; + } + size++; + } + + public void add(int index , Object o){ + checkIndex(index); + + Node newNode = new Node(o); + Node node = new Node(null); + Node pNode = head; + for(int i = 0; i < index; i++){ + node = pNode; + pNode = pNode.next; + } + + node.next = newNode; + newNode.next = pNode; + size++; + } + public Object get(int index){ + checkIndex(index); + + Node pNode = head; + for(int i = 0; i < index; i++){ + pNode = pNode.next; + } + + return pNode.data; + } + public Object remove(int index){ + checkIndex(index); + if(head == null){ + return null; + } + + if(index == 0){ + removeFirst(); + }//忘了考虑这种情况了 + + Node node = new Node(null); + Node pNode = head; + for(int i = 0; i < index; i++){ + node = pNode; + pNode = pNode.next; + } + node.next = pNode.next; + size--; + + return pNode.data; + } + + public int size(){ + return size; + } + + public void addFirst(Object o){ + Node newNode = new Node(o); + + if(head == null){ + head = newNode; + }else{ + newNode.next = head; + head = newNode; + } + size++; + } + + public void addLast(Object o){ + Node newNode = new Node(o); + if(head == null){ + head = newNode; + } + + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + } + pNode.next = newNode; + newNode.next = null; + size++; + } + + public Object removeFirst(){ + if(head == null){ + return null; + } + + Node pNode = head; + head = pNode.next; + head.next = pNode.next.next; + size--; + return pNode.data; + } + + public Object removeLast(){ + if(head == null){ + return null; + } + + Node pNode = head; + Node node = new Node(null); + while(pNode.next != null){ + node = pNode; + pNode = pNode.next; + } + + node.next = null; + size--; + return pNode.data; + } + public Iterator iterator(){ + return new LinkedListIterator(); + } + + //注意这一个问题 + public class LinkedListIterator implements Iterator { + private int position; + + @Override + public boolean hasNext() { + return position < size(); + } + + @Override + public Object next() { + if(hasNext()){ + return get(position++); + } + return null; + } + + } + + public void checkIndex(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(head == null){ + return; + } + + Stack s = new Stack<>(); + + Node currentNode = head; + while(currentNode != null){ + s.push(currentNode); + + Node nextNode = currentNode.next; + currentNode.next = null; //把链断开 + currentNode = nextNode; + } + + head = s.pop(); + + currentNode = head; + while(!s.isEmpty()){ + Node nextNode = s.pop(); + currentNode.next = nextNode; + currentNode = nextNode; + } + } + + /*if(head == null || head.next == null){ + return; + } + + Node next = null;//当前节点的后一个节点 + Node pre = null;//当前节点的前一个节点 + + while(head != null){ + next = head.next; + head.next = pre; + pre = head; + head = next; + } + head = pre; + }*/ + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(head == null || head.next == null){ + return; + } + + for(int i = 0; i <= size/2; i++){ + removeFirst(); + size--; + } + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(head == null){ + return; + } + + for(int k = i; k < i + length; k++){ + checkIndex(k); + remove(k); + } + size -= length; + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * list = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list == null){ + return new int[0]; + } + + int[] array = new int[list.size]; + int count = 0; + for(int i = 0; i < list.size; i++){ + int index = (int) list.get(i); + if(index > -1 && index < size){ + array[count] = (int) get(index); + count++; + } + } + + return Arrays.copyOf(array, count); //Arrays.copyOf(a,count)截取数组a的count长度 + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + if(list == null){ + return; + } + + for(int i = 0; i < list.size; i++){ + for(int j = 0; j < size; j++){ + if(list.get(i).equals(get(j))){ + remove(j); + size --; + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(head == null){ + return; + } + + for(int i = 0; i < size; i++){ + for(int j = i+1; j < size; j++){ + if(get(i).equals(get(j))){ + remove(j); + size--; + } + } + } + /*if(head == null){ + throw new RuntimeException("LinkedList is empty!"); + }else{ + Node pre = head; + Node cur = head; + while(cur.next != null){ + cur = cur.next; + Object data = pre.data; + while(cur.data == data){ + if(cur.next == null){ + pre.next = null; + break; + } + pre.next = cur.next; + size--; + cur =cur.next; + if(cur == null){ + break; + } + } + pre = pre.next; + } + } + */ + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(head == null){ + return; + } + + Node pre = head; + Node cur = head; + + while(cur.next != null){ + cur = cur.next; + int data = (int)cur.data; + if(data < max && data > min){ + pre.next = cur.next; + cur = cur.next; + } else { + pre = pre.next; + cur = cur.next; + } + } + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(head == null || list.size ==0 ){ + return null; + } + + LinkedList result = new LinkedList(); + + int i = 0; + int j = 0; + + while(i < this.size && j < list.size()){ + + int value1 = (int)this.get(i); + int value2 = (int)list.get(j); + + if(value1 == value2){ + result.add(value1); + i++; + j++; + } else if (value1 < value2) { + i++; + } else { + j++; + } + } + return result; + } + + /* + * 为了测试方便,引入toString()方法 + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("["); + Node node = head; + while(node != null){ + buffer.append(node.data); + if(node.next != null){ + buffer.append(","); + } + node = node.next; + } + buffer.append("]"); + + return buffer.toString(); + } + + public static void main(String args[]){ + LinkedList list7 = new LinkedList(); + + list7.add(1); + list7.add(2); + list7.add(3); + list7.add(4); + list7.add(5); + list7.add(6); + list7.add(12); + + for(int i = 0; i < list7.size(); i++){ + System.out.println(list7.get(i)); + } + } +} + + diff --git a/group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java b/group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java new file mode 100644 index 0000000000..a51e6455b3 --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java @@ -0,0 +1,309 @@ +package com.coding.basic.linklist; + +import static org.junit.Assert.*; + +import org.junit.Assert; +import org.junit.Test; + + +public class LinkedListTest { + @Test + public void testAdd() { + LinkedList l1 = new LinkedList(); + + Assert.assertEquals("[]", l1.toString()); + + l1.add(1); + l1.add(2); + l1.add(3); + l1.add(4); + + Assert.assertEquals("[1,2,3,4]", l1.toString()); + } + + @Test + public void TestSize(){ + LinkedList l2 = new LinkedList(); + + Assert.assertEquals(0, l2.size()); + + l2.add(1); + l2.add(2); + l2.add(3); + + Assert.assertEquals(3, l2.size()); + } + + @Test + public void testAddIndex(){ + LinkedList l3 = new LinkedList(); + + l3.add(1); + l3.add(2); + l3.add(3); + l3.add(4); + + l3.add(2, 6); + + Assert.assertEquals("[1,2,6,3,4]", l3.toString()); + } + + @Test + public void testGet(){ + LinkedList l4 = new LinkedList(); + l4.add(1); + l4.add(2); + l4.add(3); + l4.add(4); + + Assert.assertEquals(3, l4.get(2)); + } + + @Test + public void testRemove(){ + LinkedList l5 = new LinkedList(); + l5.add(1); + l5.add(2); + l5.add(3); + l5.add(4); + + l5.remove(3); + + Assert.assertEquals("[1,2,3]", l5.toString()); + } + + @Test + public void testAddFirst(){ + LinkedList l6 = new LinkedList(); + + l6.addFirst(1); + + Assert.assertEquals("[1]", l6.toString()); + + l6.add(2); + l6.add(3); + + l6.addFirst(2); + + Assert.assertEquals("[2,1,2,3]", l6.toString()); + } + @Test + public void testAddLast(){ + LinkedList l7 = new LinkedList(); + + l7.addLast(1); + + Assert.assertEquals("[1]", l7.toString()); + + l7.add(2); + l7.add(3); + + l7.addLast(4); + + Assert.assertEquals("[1,2,3,4]", l7.toString()); + } + @Test + public void testRmemoveFirst(){ + LinkedList l8 = new LinkedList(); + + l8.removeFirst(); + + Assert.assertEquals("[]", l8.toString()); + + l8.add(2); + l8.add(3); + + l8.removeFirst(); + + Assert.assertEquals("[3]", l8.toString()); + } + + @Test + public void testRmemoveLast(){ + LinkedList l9 = new LinkedList(); + + l9.removeLast(); + + Assert.assertEquals("[]", l9.toString()); + + l9.add(2); + l9.add(3); + + l9.removeLast(); + + Assert.assertEquals("[2]", l9.toString()); + } + + @Test + public void testReverse(){ + LinkedList list1 = new LinkedList(); + + list1.reverse(); + + Assert.assertEquals("[]", list1.toString()); + + list1.add(1); + list1.add(2); + list1.add(3); + + list1.reverse(); + + Assert.assertEquals("[3,2,1]", list1.toString()); + } + + @Test + public void testRemoveFirstHalf(){ + LinkedList list2 = new LinkedList(); + list2.removeFirstHalf(); + Assert.assertEquals("[]", list2.toString()); + + list2.add(1); + list2.removeFirstHalf(); + Assert.assertEquals("[1]", list2.toString()); + + list2.add(2); + list2.add(3); + list2.add(4); + list2.removeFirstHalf(); + + Assert.assertEquals("[3,4]", list2.toString()); + + list2.add(5); + list2.removeFirstHalf(); + + Assert.assertEquals("[4,5]", list2.toString()); + + } + @Test + public void testRemoveLength(){ + LinkedList list3 = new LinkedList(); + list3.remove(1,3); + Assert.assertEquals("[]", list3.toString()); + + list3.add(1); + list3.add(2); + list3.add(3); + list3.add(4); + list3.add(5); + list3.remove(0,1); + + Assert.assertEquals("[2,3,4,5]", list3.toString()); + } + + @Test + public void testGetElements(){ + LinkedList list4 = new LinkedList(); + LinkedList list = new LinkedList(); + + int[] array = null; + array = list4.getElements(list); + + assertArrayEquals(new int[0], array); + + list4.add(11); + list4.add(101); + list4.add(201); + list4.add(301); + list4.add(401); + list4.add(501); + list4.add(601); + list4.add(701); + list.add(1); + list.add(3); + list.add(12); + list.add(6); + + array = list4.getElements(list); + int[] result = {101,301,601}; + + assertArrayEquals(result, array); + + } + @Test + public void testSubtract(){ + LinkedList list5 = new LinkedList(); + LinkedList list = new LinkedList(); + + list5.subtract(list); + + Assert.assertEquals("[]", list5.toString()); + + list5.add(11); + list5.add(101); + list5.add(201); + list5.add(301); + list5.add(401); + list5.add(501); + list5.add(601); + list5.add(701); + list.add(11); + list.add(301); + list.add(12); + list.add(401); + + list5.subtract(list); + + Assert.assertEquals("[101,201,501,601,701]", list5.toString()); + } + @Test + public void testRemoveDuplicateValues(){ + LinkedList list6 = new LinkedList(); + + list6.removeDuplicateValues(); + + Assert.assertEquals("[]", list6.toString()); + + list6.add(1); + list6.add(2); + list6.add(2); + list6.add(10); + + list6.removeDuplicateValues(); + + Assert.assertEquals("[1,2,10]", list6.toString()); + } + + @Test + public void testRemoveRange(){ + LinkedList list7 = new LinkedList(); + + list7.removeRange(0, 10); + + Assert.assertEquals("[]", list7.toString()); + + list7.add(1); + list7.add(2); + list7.add(3); + list7.add(4); + list7.add(5); + list7.add(6); + list7.add(12); + + list7.removeRange(3, 10); + + Assert.assertEquals("[1,2,12]", list7.toString()); + } + + @Test + public void testIntersection(){ + LinkedList list8 = new LinkedList(); + + list8.add(1); + list8.add(2); + list8.add(3); + list8.add(4); + + LinkedList list9 = new LinkedList(); + list9.add(2); + list9.add(3); + list9.add(4); + list9.add(8); + + LinkedList result = new LinkedList(); + result = list8.intersection(list9); + + Assert.assertEquals("[2,3,4]", result.toString()); + + } +} + diff --git a/group06/1454385822/src/com/coding/basic/homework_04/jvm.rar b/group06/1454385822/src/com/coding/basic/homework_04/jvm.rar new file mode 100644 index 0000000000..2d7096c7b7 Binary files /dev/null and b/group06/1454385822/src/com/coding/basic/homework_04/jvm.rar differ diff --git a/group06/1454385822/src/com/coding/basic/homework_04/jvm/loader/ClassFileLoader.java b/group06/1454385822/src/com/coding/basic/homework_04/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..e4d36e04c6 --- /dev/null +++ b/group06/1454385822/src/com/coding/basic/homework_04/jvm/loader/ClassFileLoader.java @@ -0,0 +1,114 @@ +package com.coding.basic.homework_04.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + private static final int BUFFER_SIZE = 1024; + + public byte[] readBinaryCode(String className) { + byte[] result = null; + for(String path : clzPaths){ + File file = new File(getPath(path, className)); + if(!file.exists()){ + continue; + } + result = readFile(file); + } + return result; + } + + /** + * 文件数据存放在字节数组中返回 + * @param file + * @return + */ + private byte[] readFile(File file){ + FileInputStream fileInputStream; + byte[] buffer = new byte[BUFFER_SIZE]; + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + try { + fileInputStream = new FileInputStream(file); + while(byteArrayOutputStream.size() < file.length()){ + int len = fileInputStream.read(buffer); + if(len < 0){ + break; + } + byteArrayOutputStream.write(buffer, 0, len); + } + } catch (Exception e) { + e.printStackTrace(); + } + + if(byteArrayOutputStream.size() > file.length()){ + byte[] result = byteArrayOutputStream.toByteArray(); + return Arrays.copyOf(result, (int)file.length()); + } + return byteArrayOutputStream.toByteArray(); + } + + /** + * 获取真实路径路径 + * @param className + * @return + */ + private String getPath(String path ,String className){ + System.out.println(className); + String [] ways = className.split("\\."); + for (String string : ways) { + System.out.println(string); + } + StringBuilder builder = new StringBuilder(); + builder.append(path); + for (String string : ways) { + + builder.append("\\"); + builder.append(string); + } + builder.append(".class"); + System.out.println(builder.toString()); + return builder.toString(); + } + + private byte[] loadClassFile(String clzFileName) { + + return null; + } + + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath_V1(){ + + return null; + } + + + public String getClassPath(){ + StringBuilder builder = new StringBuilder(); + for(int i = 0; i < clzPaths.size(); i++){ + builder.append(clzPaths.get(i)); + if(i < clzPaths.size() - 1){ + builder.append(";"); + } + } + return builder.toString(); + } + + + + + +} \ No newline at end of file diff --git a/group06/1454385822/src/com/coding/basic/homework_04/jvm/test/ClassFileloaderTest.java b/group06/1454385822/src/com/coding/basic/homework_04/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..a0ba195077 --- /dev/null +++ b/group06/1454385822/src/com/coding/basic/homework_04/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,89 @@ +package com.coding.basic.homework_04.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coding.basic.homework_04.jvm.loader.ClassFileLoader; + +public class ClassFileloaderTest { + + + static String path1 = "C:\\Users\\yanght\\Documents\\mygit\\coding2017-1\\group06\\1454385822\\bin"; + static String path2 = "D:\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.coding.basic.homework_04.jvm.test.EmployeeV1"; +// String className = "EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1084, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coding.basic.homework_04.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= capacity){ //缓存页满了 + Node node = getNode(pageNum); + LRU(node, pageNum); + } + } + + /** + * lru算法 + * @param node + * @param pageNum + */ + private void LRU(Node node, int pageNum){ + if(node != null){ + if(last.pageNum == node.pageNum){ //缓存是last + last = node.prev; + last.next = null; + node.next = first; + first.prev = node; + node.prev = null; + first = node; + }else if(last.pageNum != node.pageNum && first.pageNum != node.pageNum){ + //缓存在first和last的中间范围 + node.prev.next = node.next; + node.next.prev = node.prev; + node.prev = null; + node.next = first; + first = node; + } + }else{ + //新缓存 + last = last.prev; + last.next = null; + node = new Node(pageNum); + node.next = first; + first.prev = node; + first = node; + } + } + + /** + * 根据数据在缓存中获取节点 + * @param pageNum + * @return + */ + private Node getNode(int pageNum){ + Node node = first; + while(node != null){ + if(node.pageNum == pageNum){ + return node; + } + node = node.next; + } + return null; + } + + public int size(){ + int num = 0; + Node node = first; + while(node != null){ + num++; + node = node.next; + } + return num; + } + + 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/group06/1454385822/src/com/coding/basic/homework_04/lru/LRUPageFrameTest.java b/group06/1454385822/src/com/coding/basic/homework_04/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..330dbf4836 --- /dev/null +++ b/group06/1454385822/src/com/coding/basic/homework_04/lru/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.homework_04.lru; + +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/group06/2415980327/CodeSE01/down2.png b/group06/2415980327/CodeSE01/down2.png new file mode 100644 index 0000000000..4c8bf3db8f Binary files /dev/null and b/group06/2415980327/CodeSE01/down2.png differ diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/LinkedList.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/LinkedList.java new file mode 100644 index 0000000000..261d8f5427 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/LinkedList.java @@ -0,0 +1,456 @@ +package com.pxshuo.se03.basic; + +import com.pxshuo.se01.basic.Iterator; + +public class LinkedList implements List { + + private Node head; + private Node last; + private int size = 0; + + private String outOfBoundsMsg(int index) { + return "Index: "+index+", Size: "+size; + } + + private boolean isElementIndex(int index) { + return index >= 0 && index < size; + } + + private void checkElementIndex(int index) { + if (!isElementIndex(index)) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + private boolean isPositionIndex(int index) { + return index >= 0 && index <= size; + } + + private void checkPositionIndex(int index) { + if (!isPositionIndex(index)) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + /** + * 获取一个节点,不进行范围检查 + * @param index 位置 + */ + private Node getNode(int index){ + Node node = head; + for (int i = 0; i < index; i++) { + node = node.next; + } + return node; + } + + /** + * 添加一个节点 + * @param o + */ + public void add(Object o){ + Node node = new Node(o); + Node l = last; + last = node; + + if (head == null) { + head = node; + } + else{ + l.next = last; + } + size ++; + } + + /** + * 在某个位置进行插入 + * @param index 位置 + * @param o 插入的元素 + */ + public void add(int index , Object o){ + checkPositionIndex(index); + + if (size == index) { + add(o); + } + else if (0 == index){ + addFirst(o); + } + else { + Node node = new Node(o); + Node preNode = getNode(index - 1); + + node.next = preNode.next; + preNode.next = node; + + size++; + } + } + + /** + * 获取一个节点 + * @param index 位置 + */ + public Object get(int index){ + checkElementIndex(index); + return getNode(index).data; + } + + + public Object remove(int index){ + checkElementIndex(index); + Object data = null; + if (index == 0) { + data = removeFirst(); + } + else if(index == size) { + data = removeLast(); + } + else { + Node pre = getNode(index - 1); + data = pre.next.data; + pre.next = pre.next.next; + size --; + } + return data; + } + + public int size(){ + return size; + } + + /** + * 添加第一个元素 + * @param o + */ + public void addFirst(Object o){ + if (head == null) { + add(o); + return; + } + + Node node = new Node(o); + node.next = head; + head = node; + size ++; + } + /** + * 添加最后的元素 + * @param o + */ + public void addLast(Object o){ + add(o); + } + /** + * 移除最初元素 + * @return + */ + public Object removeFirst(){ + checkElementIndex(0);//检查首位是否有元素 + if (head == last) { + last = null; + } + Object data = head.data; + head = head.next; + size --; + return data; + } + + /** + * 移除最后的元素 + * @return + */ + public Object removeLast(){ + checkElementIndex(0);//检查首位是否有元素 + if (head == last) { + return removeFirst(); + } + Object data = last.data; + last = getNode(size - 2); + last.next = null; + return data; + } + public Iterator iterator(){ + return new LinkedListIterator(); + } + + public void display() { + Node cur = head; + int i = 0; + while(cur != null && i < 1000) + { + System.out.println(i + ":" + cur.data.toString()); + cur = cur.next; + } + } + + public String getResult() { + Node cur = head; + int i = 0; + String result = ""; + while(cur != null && i < 1000) + { + result += cur.data.toString(); + cur = cur.next; + if (cur != null) { + result += ","; + } + } + + return result; + } + + private static class Node{ + Object data; + Node next; + + public Node(Object o){ + data = o; + } + } + + private class LinkedListIterator implements Iterator{ + Node position = null; + + public LinkedListIterator() { + this.position = head; + } + + @Override + public boolean hasNext() { + if (position == null) { + return false; + } + return true; + } + + @Override + public Object next() { + Object data = position.data; + position = position.next; + return data; + } + + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + checkElementIndex(0); + if (size == 1) { + return; + } + + last = head; + Node pre = null; + Node next = null; + while(head.next != null){ + next = head.next; + head.next = pre; + pre = head; + head = next; + } + head.next = pre; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if (size < 2) { + head = null; + last = null; + size = 0; + } + + int half = size/2; + Node halfPre = getNode(half - 1); + head = halfPre.next; + halfPre.next = null; + size = size - half; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if (length < 1) { + return; + } + checkElementIndex(i); + checkElementIndex(i + length - 1); + + Node pre = null;//删除元素的前一个 + Node nextPre = getNode(i + length - 1);//删除元素的最后一个 + if (i != 0) { + pre = getNode(i - 1); + } + + if (pre != null) { + pre.next = nextPre.next; + } + else { + head = nextPre.next; + } + + if (nextPre.next == null) { + last = pre; + } + + nextPre = null; + size -= length; + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] listResult = new int[list.size]; + int i = 0; + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + int index = Integer.parseInt(iterator.next().toString()); + listResult[i] = Integer.parseInt(get(index).toString()); + i ++; + } + return listResult; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + public void subtract(LinkedList list){ + int index = 0; + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + Object del = iterator.next(); + for (index = 0;index < size;index ++) { + if (((String)get(index)).equals((String)del)) { + remove(index); + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + checkElementIndex(0); + Node cur = head; + while(cur.next != null){ + String curData = (String)(cur.data); + String nextData = (String)(cur.next.data); + if (curData.equals(nextData)) { + size --; + if (cur.next == last) { + cur.next = null; + last = cur; + }else { + cur.next = cur.next.next; + } + } + else { + cur = cur.next; + } + + } + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + checkElementIndex(0); + Node minNode = null;//删除的前一个节点 + Node maxNode = null; + Node cur = head; + Node pre = null; + int delSize = 0; + + while(cur != null){ + int curVal = Integer.parseInt((String)(cur.data)); + if (minNode == null && delSize == 0) { + if (curVal > min) {//开始删除 + minNode = pre; + delSize ++; + } + } + + if (delSize != 0) { + if (curVal > max) {//结束删除 + maxNode = cur; + break;//跳出循环 + } + else { + delSize ++; + } + } + pre = cur; + cur = cur.next; + } + //进行删除 + if (delSize - 1 == size) {//删除全部 + head = null; + last = null; + size = 0; + return; + } + else if (delSize == 0) {//没有删除任务 + return; + } + else if (minNode == null) {//从头部开始删除 + head = maxNode; + } + else if (maxNode == null) {//删除尾部 + last = minNode; + last.next = null; + } + else {//删除中间部分 + minNode.next = maxNode; + } + + size -= delSize - 1; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList result = new LinkedList(); + Node cur = head; + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + Object data = iterator.next(); + int dataNum = Integer.parseInt((String)data); + while(cur != null){ + int curData = Integer.parseInt((String)(cur.data)); + if(curData == dataNum){ + result.add(data); + break; + } + else if(dataNum < curData){ + break; + } + cur = cur.next; + } + } + return result; + } +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/List.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/List.java new file mode 100644 index 0000000000..bd0aca9a4c --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/List.java @@ -0,0 +1,9 @@ +package com.pxshuo.se03.basic; + +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/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/DownloadThread.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/DownloadThread.java new file mode 100644 index 0000000000..36d2555ab6 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/DownloadThread.java @@ -0,0 +1,51 @@ +package com.pxshuo.se03.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.pxshuo.se03.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + + CyclicBarrier barrier; + String localFile; + + public DownloadThread( Connection conn, int startPos, int endPos,String localFile,CyclicBarrier barrier){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + + this.localFile = localFile; + this.barrier = barrier; + } + public void run(){ + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + try { + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + + file.seek(startPos); + file.write(data); + file.close(); + + conn.close(); + barrier.await(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BrokenBarrierException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloader.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloader.java new file mode 100644 index 0000000000..8d78d08a62 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloader.java @@ -0,0 +1,140 @@ +package com.pxshuo.se03.download; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.pxshuo.se03.download.api.Connection; +import com.pxshuo.se03.download.api.ConnectionException; +import com.pxshuo.se03.download.api.ConnectionManager; +import com.pxshuo.se03.download.api.DownloadListener; + + +public class FileDownloader { + + private final static int DOWNLOAD_THREAD_NUM = 3; + + private String url; + private String filePath; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url,String filePath) { + this.url = _url; + this.filePath = filePath; + } + + 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 cyclicBarrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM,new Runnable() { + + @Override + public void run() { + // TODO Auto-generated method stub + listener.notifyFinished(); + } + }); + + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + System.out.println(length); + + createPlaceHolderFile(this.filePath, length); + + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length); + + for(int i = 0; i < DOWNLOAD_THREAD_NUM; i++){ + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + filePath, + cyclicBarrier); + + thread.start(); + } + + } catch (ConnectionException | 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; + } + + /** + * 先在硬盘中占据一部分空间 + * @param filePath + * @param length + * @throws IOException + */ + private void createPlaceHolderFile(String filePath,int length) throws IOException{ + RandomAccessFile file = new RandomAccessFile(filePath, "rw"); + + for (int i = 0; i < length; i++) {//初始化一个文件 + file.write(0); + } + + file.close(); + } + + private int[][] allocateDownloadRange(int threadNum,int length){ + int[][] ranges = new int[threadNum][2]; + + int eachThreadSize = length/threadNum; + int left = length % threadNum; + + for (int i = 0; i < threadNum; i++) { + int startPos = i * eachThreadSize; + int endPos = (i + 1) * eachThreadSize - 1; + + if (i == (threadNum - 1)) { + endPos += left; + } + + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + + return ranges; + } +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloaderTest.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloaderTest.java new file mode 100644 index 0000000000..d00fc54677 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloaderTest.java @@ -0,0 +1,64 @@ +package com.pxshuo.se03.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.pxshuo.se03.download.api.ConnectionManager; +import com.pxshuo.se03.download.api.DownloadListener; +import com.pxshuo.se03.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + public static void main(String[] args) { + FileDownloaderTest test = new FileDownloaderTest(); + test.testDownload(); + } + + public void testDownload() { + + String url = "https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3c6d55fbb2fb4316352d920a22a4462309f7d394.jpg"; + String filePath = "C://Users//Pxshuo//Desktop//test.png"; + + FileDownloader downloader = new FileDownloader(url,filePath); + + + 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/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/Connection.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/Connection.java new file mode 100644 index 0000000000..27ad88a2ac --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.pxshuo.se03.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/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionException.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionException.java new file mode 100644 index 0000000000..c0afde1b28 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.pxshuo.se03.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionManager.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionManager.java new file mode 100644 index 0000000000..b3c94ba85c --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.pxshuo.se03.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/DownloadListener.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/DownloadListener.java new file mode 100644 index 0000000000..daea7b952f --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.pxshuo.se03.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionImpl.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..265923f7b4 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionImpl.java @@ -0,0 +1,95 @@ +package com.pxshuo.se03.download.impl; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; +import java.util.Arrays; + +import com.pxshuo.se03.download.api.Connection; + +class ConnectionImpl implements Connection{ + + private URL url; + private HttpURLConnection connect = null; + private int length;//不知道每次都确定一下是否比较好 + + private static int BUFFER_SIZE = 1024; + + /** + * 初始化 + * @param destUrl + */ + public ConnectionImpl(String destUrl) { + // TODO Auto-generated constructor stub + + try { + url = new URL(destUrl); + length = -1; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + connect = (HttpURLConnection)url.openConnection(); + connect.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream is = connect.getInputStream(); + + byte[] buff = new byte[BUFFER_SIZE]; + int totalLength = endPos - startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + while(baos.size() < totalLength){ + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff,0,len); + } + + if (baos.size() > totalLength) { + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLength); + } + + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + int length = -1; + try { + connect = (HttpURLConnection) url.openConnection(); + connect.setRequestMethod("GET"); + connect.setConnectTimeout(10000); + if (connect.getResponseCode() == 200) { + length = connect.getContentLength(); + } + System.out.println("error:" + length); + connect.disconnect(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return length; + } + + @Override + public void close() { + if (connect != null) { + connect.disconnect(); + } + } + +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionManagerImpl.java b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..b10970b5f9 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.pxshuo.se03.download.impl; + +import com.pxshuo.se03.download.api.Connection; +import com.pxshuo.se03.download.api.ConnectionException; +import com.pxshuo.se03.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/test/ConnectTest.java b/group06/2415980327/CodeSE01/src/com/pxshuo/test/ConnectTest.java new file mode 100644 index 0000000000..2b75370625 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/test/ConnectTest.java @@ -0,0 +1,184 @@ +package com.pxshuo.test; + +import java.io.BufferedInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Vector; + + +/** + * 测试实现下载功能 + * @author Pxshuo + * + */ + +public class ConnectTest { + + public static void main(String[] args) { + ConnectTest test = new ConnectTest(); + String url = "https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3c6d55fbb2fb4316352d920a22a4462309f7d394.jpg"; + try { + //test.saveToFile("https://code.getmdl.io/1.3.0/mdl-template-dashboard.zip", "./down.zip"); + //test.saveToFile("https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3c6d55fbb2fb4316352d920a22a4462309f7d394.jpg", "./down.png"); +// ConnectionImpl ci = new ConnectionImpl(url); +// FileOutputStream fos = new FileOutputStream("down.png"); +// int length = ci.getContentLength(); +// System.out.println(length); +// fos.write(ci.read(0, length - 1),0,length); +// fos.close(); + System.out.println("success"); + + URL url2 = new URL(url); + HttpURLConnection connection = (HttpURLConnection) url2.openConnection(); + //connection.setRequestMethod("GET"); + //connection.setConnectTimeout(10000); + + FileOutputStream fos = null; + BufferedInputStream bis = null; + byte[] buf = new byte[connection.getContentLength()]; + bis = new BufferedInputStream(connection.getInputStream()); + //建立文件 + fos = new FileOutputStream("down2.png"); + int size = 0;//= bis.read(buf); + int offset = 0; + while((size = bis.read(buf, 0, buf.length)) != -1){ + } + fos.write(buf,0,buf.length); + //保存文件 +// while((size = bis.read(buf)) != -1){ +// fos.write(buf,0,size); +// } + fos.close(); + bis.close(); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public final static boolean DEBUG = true; + private static int BUFFER_SIZE = 8096;//缓存大小 + private Vector vDownload = new Vector<>();//Url列表 + private Vector vFileList = new Vector<>();//文件名 + + public ConnectTest() { + // TODO Auto-generated constructor stub + } + + /** + * 清除下载列表 + */ + public void resetList(){ + vDownload.clear(); + vFileList.clear(); + } + + /** + * 增加下载列表项 + * @param url + * @param filename + */ + public void addItem(String url,String filename){ + vDownload.add(url); + vFileList.add(filename); + } + + /** + * 根据列表下载资源 + */ + public void downLoadByList() { + String url = null; + String filename = null; + + for(int i = 0;i < vDownload.size();i++){ + url = (String)vDownload.get(i); + filename = (String)vFileList.get(i); + + try { + saveToFile(url, filename); + } catch (IOException e) { + // TODO Auto-generated catch block + if (DEBUG) { + System.out.println("资源[" + url + "]下载失败!!!"); + } + e.printStackTrace(); + } + } + + if (DEBUG) { + System.out.println("下载完成"); + } + } + + public void saveToFile(String destUrl,String filename) throws IOException { + FileOutputStream fos = null; + BufferedInputStream bis = null; + HttpURLConnection httpUrl = null; + URL url = null; + byte[] buf = new byte[BUFFER_SIZE]; + int size = 0; + + //建立连接 + url = new URL(destUrl); + httpUrl = (HttpURLConnection)url.openConnection(); + //链接指定的资源 + //httpUrl.connect(); + //获取网络输入流 + bis = new BufferedInputStream(httpUrl.getInputStream()); + //建立文件 + fos = new FileOutputStream(filename); + + if (DEBUG) { + System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + filename + "]"); + } + + int byteLength = 0; + + //保存文件 + while((size = bis.read(buf)) != -1){ + fos.write(buf,0,size); + byteLength += size; + } + System.out.println(httpUrl.getContentLength() + ":" + byteLength); + fos.close(); + bis.close(); + httpUrl.disconnect(); + } + + public void saveToFile(String destUrl,String filename,int start,int end) throws IOException { + FileOutputStream fos = null; + BufferedInputStream bis = null; + HttpURLConnection httpUrl = null; + URL url = null; + byte[] buf = new byte[BUFFER_SIZE]; + int size = 0; + + //建立连接 + url = new URL(destUrl); + httpUrl = (HttpURLConnection)url.openConnection(); + //链接指定的资源 + httpUrl.connect(); + httpUrl.setRequestProperty("Range", "bytes=" + start + "-" + end); + //获取网络输入流 + bis = new BufferedInputStream(httpUrl.getInputStream()); + //建立文件 + fos = new FileOutputStream(filename); + + if (DEBUG) { + System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + filename + "]"); + } + + //保存文件 + while((size = bis.read(buf)) != -1){ + fos.write(buf,0,size); + } + + fos.close(); + bis.close(); + httpUrl.disconnect(); + } +} diff --git a/group06/2415980327/CodeSE01/src/com/pxshuo/test/Test.java b/group06/2415980327/CodeSE01/src/com/pxshuo/test/Test.java index 9737d269e8..95c1fef665 100644 --- a/group06/2415980327/CodeSE01/src/com/pxshuo/test/Test.java +++ b/group06/2415980327/CodeSE01/src/com/pxshuo/test/Test.java @@ -1,59 +1,13 @@ package com.pxshuo.test; - -import com.pxshuo.se01.basic.Iterator; -import com.pxshuo.se01.basic.TreeData; -import com.pxshuo.se01.basic.impl.ArrayList; -import com.pxshuo.se01.basic.impl.BinaryTree; -import com.pxshuo.se01.basic.impl.LinkedList; -import com.pxshuo.se01.basic.impl.Queue; -import com.pxshuo.se01.basic.impl.Stack; +import com.pxshuo.se03.basic.LinkedList; public class Test { public static void main(String[] args) { -// LinkedList arrayList = new LinkedList(); -// arrayList.add("hello1"); -// arrayList.add("hello2"); -// arrayList.add(9,"hello3"); -// //arrayList.add(10,"hello4"); -// arrayList.addLast("hi"); -// arrayList.addLast("hihi"); -// arrayList.addFirst("hi1"); -// arrayList.removeFirst(); -// arrayList.removeLast(); -// arrayList.add(1,"hi1"); -// arrayList.remove(1); -// //arrayList.add(0, "hi"); -// //arrayList.remove(8); -// //arrayList.remove(0); -// for (Iterator iterator = arrayList.iterator(); iterator.hasNext();) { -// System.out.println("hi"+iterator.next()); -// } - //Queue queue = new Queue(); -// Stack stack = new Stack(); -// -// for (int i = 0; i < 10; i++) { -// //queue.enQueue("test-" + i); -// stack.push("test-" + i); -// } -// for(int i =0; i< 11; i++) -// { -// System.out.println(stack.pop()); -// } -// stack.push("test-" + 233); -// System.out.println(stack.pop()); - - BinaryTree binaryTree = new BinaryTree(); - binaryTree.add(new TreeData(5)); - binaryTree.add(new TreeData(2)); - binaryTree.add(new TreeData(7)); - binaryTree.add(new TreeData(1)); - binaryTree.add(new TreeData(6)); - binaryTree.add(new TreeData(4)); - binaryTree.add(new TreeData(8)); - - System.out.println(binaryTree.get(5).getClass()); - - //binaryTree.display(); + LinkedList obj = new LinkedList(); + obj.add("3"); + obj.add("7"); + obj.add("10"); + System.out.println(obj.getResult()); } } diff --git a/group06/2415980327/CodeSE01/src/test/com/pxshuo/se03/array/LinkedListUntilTest.java b/group06/2415980327/CodeSE01/src/test/com/pxshuo/se03/array/LinkedListUntilTest.java new file mode 100644 index 0000000000..962d938479 --- /dev/null +++ b/group06/2415980327/CodeSE01/src/test/com/pxshuo/se03/array/LinkedListUntilTest.java @@ -0,0 +1,144 @@ +package test.com.pxshuo.se03.array; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.pxshuo.se03.basic.LinkedList; + +public class LinkedListUntilTest { + private LinkedList obj; + + @Before + public void init() { + obj = new LinkedList(); + } + + @After + public void clear() { + obj = null; + } + + @Test + public void reverseTest() { + obj.add("3"); + obj.add("7"); + obj.add("10"); + obj.reverse(); + Assert.assertEquals("10,7,3", obj.getResult()); + } + + @Test + public void removeFirstHalfTest() { + obj.add("2"); + obj.add("5"); + obj.add("7"); + obj.add("8"); + obj.add("10"); + obj.removeFirstHalf(); + Assert.assertEquals("7,8,10", obj.getResult()); + Assert.assertEquals(3, obj.size()); + } + + @Test + public void removeLengthTest() { + obj.add("2"); + obj.add("5"); + obj.add("7"); + obj.add("8"); + obj.add("10"); + obj.remove(1,3); + Assert.assertEquals("2,10", obj.getResult()); + Assert.assertEquals(2, obj.size()); + } + + @Test + public void getElementsTest() { + obj.add("11"); + obj.add("101"); + obj.add("201"); + obj.add("301"); + obj.add("401"); + obj.add("501"); + obj.add("601"); + obj.add("701"); + LinkedList getList = new LinkedList(); + getList.add("1"); + getList.add("3"); + getList.add("4"); + getList.add("6"); + Assert.assertArrayEquals(new int[]{101,301,401,601}, obj.getElements(getList)); + } + + @Test + public void subtractTest() { + obj.add("11"); + obj.add("101"); + obj.add("201"); + obj.add("301"); + obj.add("401"); + obj.add("501"); + obj.add("601"); + obj.add("701"); + LinkedList getList = new LinkedList(); + getList.add("101"); + getList.add("301"); + getList.add("401"); + getList.add("601"); + obj.subtract(getList); + Assert.assertEquals("11,201,501,701", obj.getResult()); + } + + @Test + public void removeDuplicateValuesTest() { + obj.add("11"); + obj.add("101"); + obj.add("101"); + obj.add("301"); + obj.add("401"); + obj.add("401"); + obj.add("601"); + obj.add("601"); + obj.removeDuplicateValues(); + Assert.assertEquals("11,101,301,401,601", obj.getResult()); + } + + @Test + public void removeRangeTest() { + obj.add("11"); + obj.add("101"); + obj.add("201"); + obj.add("301"); + obj.add("401"); + obj.add("501"); + obj.add("601"); + obj.add("701"); + obj.removeRange(200, 600); + Assert.assertEquals("11,101,601,701", obj.getResult()); + Assert.assertEquals(4, obj.size()); + + } + + @Test + public void intersectionTest() { + obj.add("11"); + obj.add("101"); + obj.add("201"); + obj.add("301"); + obj.add("401"); + obj.add("501"); + obj.add("601"); + obj.add("701"); + + LinkedList getList = new LinkedList(); + getList.add("10"); + getList.add("101"); + getList.add("301"); + getList.add("402"); + getList.add("601"); + + Assert.assertEquals("101,301,601", obj.intersection(getList).getResult()); + + } +} diff --git "a/group06/2415980327/\346\226\207\347\253\240/SE02_\347\254\254\344\272\214\345\221\250\345\215\232\345\256\242_\345\205\263\344\272\216Java\347\232\204\345\217\215\345\260\204\346\234\272\345\210\266.md" "b/group06/2415980327/\346\226\207\347\253\240/SE02_\347\254\254\344\272\214\345\221\250\345\215\232\345\256\242_\345\205\263\344\272\216Java\347\232\204\345\217\215\345\260\204\346\234\272\345\210\266.md" new file mode 100644 index 0000000000..3ac75a6b86 --- /dev/null +++ "b/group06/2415980327/\346\226\207\347\253\240/SE02_\347\254\254\344\272\214\345\221\250\345\215\232\345\256\242_\345\205\263\344\272\216Java\347\232\204\345\217\215\345\260\204\346\234\272\345\210\266.md" @@ -0,0 +1,81 @@ +# 第二周博客 关于Java的反射机制 + +## 前言 + +​ 自从毕业以来,逐渐的接触了Java的开发。虽然也接触了两年有余吧,但总是停留在写一些基础业务流程方面。在工作中,长此以往,也是如此了。所以也是给自己一个机会来了解一些进阶的东西来充实自己。 + +​ 对于Java的反射机制,我不会用,也不懂的原理,不敢随意妄言,只是简单记录一下本次对于Java反射作业的认识,同时梳理一下自己的思路,为了日后更加深刻的了解做一些铺垫吧。 + +## 一、结构梳理 + +​ 本次的作业是一个轻量级的Struts框架的模拟。实际上来说,以前倒是做过一次,只是时间有点久远,或许是没有及时的温习巩固,后来就慢慢的忘记了。此次再次进行模拟,也是参考之前的程序进行编写的。 + +​ 作为一个轻量级的Struts框架,老师给出了一个思路。这个思路是 + +1. 通过传入actionName与参数来使用Struts框架,生成一个View,这个View可以用来获取Html页面与传递数据。 + +2. Struts框架生成View是通过读取xml配置文件来进行生成的。 + + + 根据这个思路来看的话,我们需要: + + * 一个View来展示与保存结果。 + * 一个Struts的框架来利用反射机制,生成结果。 + * 一个xml的配置文件来供Struts进行读取。 + * 还需要一个Action类书写业务流程,为Struts的反射提供实体。 + * 一个Test用于测试,这个不是核心的类了就是了。 + + 而我们看到的作业的初始框架也就分为这几部分了。这些类的运行过程就是Struts根据参数来读取xml文件,利用反射生成Action类,并运行其中固定的函数,并将结果封装成View返回。 + + + +## 二、反射的使用 + +代码示例: + +~~~java +//反射实例化一个对象 +Object action = Class.forName(actionClass).newInstance(); + +//调用exectue +Method exectue = action.getClass().getDeclaredMethod("execute"); +String result = (String)exectue.invoke(action); + +//生成返回列表 +Map actionParam = new HashMap<>(); +Method[] methods = action.getClass().getDeclaredMethods(); +for (Method method : methods) { + if (method.getName().startsWith("get")) { + String methodName = Tools.lowerFirst(method.getName().substring(3)); + String methodValue = (String)method.invoke(action); + actionParam.put(methodName, methodValue); + } +} +~~~ + +### 2.1 反射实例化一个对象 + +​ 反射实例化一个对象是使用``` Object obj = Class.forName("className").newInstance``` 来实现的。通过这种方式,我们可以通过类名(完整的,带包名的字符串)来新建一个实例。可以通过字符串来新建实例也就意味着我们可以通过动态的方式来**new** 一个对象,提供了很大的灵活性。 + +### 2.2 反射调用实例中的方法 + +​ 通过反射调用是使用``` Method method = obj.getClass().getDeclaredMethod("methodName")``` 来获取方法体,并使用``` method.invoke(obj);//obj为一个实例``` 通过这种方式来执行一个函数。 + +​ 这个虽然很灵活,但我用的不是很多,想来如何向函数中传递参数以及如何强制执行私有函数,还有如何防止这种反射机制我还未了解,有时间研究一下,再进行相应的更新。 + +### 2.3 获取方法列表 + +​ 可以通过``` methods = obj.getClass().getDeclaredMethods()``` 来获取实例中所有的方法。 + +​ 不知道有么有方法可以往实例中注入一些方法呢? + +### 2.4 这些可以做什么 + +​ 这些功能这么灵活,那么应该如何使用它们呢?是不是可以开发一个自由度特别特别高的程序呢?感觉上是可以的吧,就像是一个更专业向的框架一样。是不是一个好的想法呢~ + + + +## 三、POI的XML文件读取 + +​ 这次作业,感觉比较让人头大的应该是xml文件的读取了,但是只是属于比较繁琐,但是也比较好理解的范畴,随用随查即可,不像反射那样可以有灵活的运用,所以就不做重点的介绍。 + diff --git "a/group06/2415980327/\346\226\207\347\253\240/SE03_\347\254\254\344\270\211\345\221\250\345\215\232\345\256\242_Java\347\232\204\345\244\232\347\272\277\347\250\213\343\200\201\344\270\213\350\275\275\344\270\216\346\226\207\344\273\266IO.md" "b/group06/2415980327/\346\226\207\347\253\240/SE03_\347\254\254\344\270\211\345\221\250\345\215\232\345\256\242_Java\347\232\204\345\244\232\347\272\277\347\250\213\343\200\201\344\270\213\350\275\275\344\270\216\346\226\207\344\273\266IO.md" new file mode 100644 index 0000000000..5cf7dbf6b9 --- /dev/null +++ "b/group06/2415980327/\346\226\207\347\253\240/SE03_\347\254\254\344\270\211\345\221\250\345\215\232\345\256\242_Java\347\232\204\345\244\232\347\272\277\347\250\213\343\200\201\344\270\213\350\275\275\344\270\216\346\226\207\344\273\266IO.md" @@ -0,0 +1,96 @@ +# 第三周博客 Java的多线程、下载与文件IO + +# 前言 + +​ Java里面目前三个最让我头疼的地方在这次的作业中一次性的全都出现了。虽然是一个专科出身的程序员,但是自认为在Java上对于这方面的掌握应该是远远不及经历过培训的同学们的。这是自己的一大弱点,对于一个新的技术,不能系统的去进行学习与研究。对于此,只能是慢慢地区梳理与使用才是了。 + +​ 对于本次的作业,显得异常的吃力,最后也是只能等到老师的讲解视频出来之后才慢慢跟着老师的思路去编码,所以再次的梳理一次程序,让自己有一个更加清晰的概念吧。 + +## 一、总体结构 + +​ 本次的作业被分为了三个包 + +* download + +* download.api + +* download.impl + + 在API接口中,有四个接口文件,其中异常接口未被实现,其他三个,分别是Connection,ConnectionManager和DownloadListener分别在impl或者程序运行中进行了实现。这种接口形式的结构可以在没有业务代码的情况下,整理好整个程序运行的框架,剩下就可以再填写.目前来看,这方面的能力需要多加练习 + + 程序主体流程包含了测试类、多线程下载类与网络连接管理类。 + +## 二、测试程序 + +​ 感觉实际上测试类可以再封装一次,虽然会更加方便地使用,但是是否会牺牲很多的灵活性呢?还是看实际的应用吧。正所谓适可而止,过犹不及。 + +​ 从测试来看的话,我们将url与文件地址传递到下载类中去,之后再在其中设置网络连接的管理类与下载完成的回调函数。这个回调函数是在所有线程全部完成之后进行回调。接下来开始下载,然后通过回调函数中的标识位来循环判断下载的进度。 + + + +## 三、多线程下载类 + +主流程: + +​ 1、使用CyclicBarrier来监测多个线程的结束与否,使用方法是在创建线程的run方法最后使用``` barrier.await()``` 来执行监测 + +​ 2、然后通过网络连接管理类获取到connection的相关信息,我们就可以根据*连接的长度* 来使用RandomAccessFile创建一个空白文件来确定硬盘空间足够。在之后各个线程下载完毕就会改写这个文件相关部分,从而完成文件的合并。 + +​ 3、根据下载的线程数来分配每个线程需要下载的部分,并开始创建线程,进行下载。 + +单个下载线程: + +​ 通过RandomAccessFile将下载下来的byte[]写入文件中,通过``` file.seek(index)``` 来确定写入文件的位置。 + + + +## 四、网络连接类 + +​ 本次作业通过管理类将连接类隐藏了起来。连接类只是对包内可见,这样,程序的封装性显得很好,值得学习。 + +​ 代码示例: + +```java +@Override +public byte[] read(int startPos, int endPos) throws IOException { + //创建连接 + connect = (HttpURLConnection)url.openConnection(); + //纠结了许久的问题,原来是在setRequestProperty之前不可以使用getContentLength + connect.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + //获取数据 + InputStream is = connect.getInputStream(); + byte[] buff = new byte[BUFFER_SIZE];//建立临时缓存区 + int totalLength = endPos - startPos + 1; + //byte数组输出流,如此看的话,命名还是很有意思的 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + //将输入流中的数据先读到缓存区中,再将缓存区中的数据写入输出流中 + while(baos.size() < totalLength){ + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff,0,len); + } + + //防止数组越界。这也就一位置上方的len应该只有-1和1024两种值吧,所以最后一次的读取会造成有少量的留白,这个操作是用来去除留白的。 + if (baos.size() > totalLength) { + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLength);//转成byte[]的一种方法 + } + + return baos.toByteArray();//转成byte[]的另一种方法 +} + +//这个byte[]如何使用呢? +RandomAccessFile file = new RandomAccessFile("filename", "rw"); +file.seek(startPos); +file.write(data);//放在这里写入即可。 +file.close(); +``` + + + + + diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/array/ArrayUtil.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/array/ArrayUtil.java index b807a9b321..78bd364577 100644 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/array/ArrayUtil.java +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/array/ArrayUtil.java @@ -20,6 +20,10 @@ public class ArrayUtil { */ public static int[] reverseArray(int[] origin){ int length = origin.length; + if(origin == null || length == 0){ + return null; + } + for(int i=0;i collection){ + public static int[] returnByIntArray(Collection collection){ int[] returnArray = new int[collection.size()]; int i = 0; for(Iterator it = collection.iterator(); it.hasNext();){ diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedList.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedList.java deleted file mode 100644 index 007a6e48c3..0000000000 --- a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedList.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.github.chaoswang.learning.java.collection.myown; - -import java.util.NoSuchElementException; - -public class MyLinkedList { - private int size = 0; - private Node head = null; - private Node tail = null; - - // - public void add(E element){ - Node tmp = new Node(element, null); - if(tail == null){ - head = tmp; - }else{ - tail.next = tmp;; - } - tail = tmp; - size++; - } - - public void add(int index, E element){ - if(index < 0 || index > size){ - throw new IndexOutOfBoundsException(); - } - Node tmpBefore = getElement(index -1); - Node tmpAfter = getElement(index); - Node tmp = new Node(element, tmpAfter); - tmpBefore.next = tmp; - - } - - public void addFirst(E element){ - Node tmp = new Node(element, null); - if(head != null){ - tmp.next = head; - }else{ - tail = tmp; - } - head = tmp; - } - - public E removeFirst(){ - if(size <= 0){ - throw new NoSuchElementException(); - } - Node tmp = head; - head = head.next; - return (E)tmp.element; - } - - // - public E remove(int index) { - if(index < 0 || index >= size()){ - throw new IndexOutOfBoundsException(); - } - Node tmpBeore = this.getElement(index-1); - Node tmp = this.getElement(index); - Node tmpNext = this.getElement(index+1); - tmpBeore.next = tmpNext; - size--; - return (E)tmp.element; - } - - // - public E get(int index){ - return (E)this.getElement(index).element; - } - - public int size() { - return size; - } - - @Override - public String toString() { - if(head == null){ - return "[]"; - } - StringBuffer sb = new StringBuffer("["); - Node tmp = head; - while(tmp != null){ - sb.append(tmp.element.toString()); - sb.append(","); - tmp = tmp.next; - } - String returnStr = sb.toString(); - returnStr = returnStr.substring(0, returnStr.length()-1); - return returnStr + "]"; - } - - private Node getElement(int index) { - Node tmp = head; - for(int i=0;i list = new ArrayList(); + + try{ + for(int i=1; i<=threadNum; i++){ + Connection conn = cm.open(url); + Thread dt = new DownloadThread(conn, threadNum, i); + dt.start(); + list.add(dt); + } + }catch(ConnectionException e){ + e.printStackTrace(); + return; + } + + while(true){ + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + if(!isAllFinished(list)){ + continue; + } + System.out.println("finished, cost time:" + (System.currentTimeMillis() - startTime)); + listener.notifyFinished(); + break; + } + } + + private boolean isAllFinished(ArrayList list){ + for(Thread t : list){ + if(t.getState() != Thread.State.TERMINATED){ + return false; + } + } + return true; + } + + 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/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/Connection.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/Connection.java new file mode 100644 index 0000000000..ca00c5e086 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/Connection.java @@ -0,0 +1,23 @@ +package com.github.chaoswang.learning.java.downloader.api; + +import java.io.IOException; + +public interface Connection { + /** + * ʼͽλã ȡݣ ֵֽ + * @param startPos ʼλã 0ʼ + * @param endPos λ + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * õݵij + * @return + */ + public int getContentLength(); + + /** + * ر + */ + public void close(); +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionException.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionException.java new file mode 100644 index 0000000000..bfbf533558 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionException.java @@ -0,0 +1,10 @@ +package com.github.chaoswang.learning.java.downloader.api; + +public class ConnectionException extends Exception { + private static final long serialVersionUID = -6832188361613061488L; + + public ConnectionException(String message){ + super(message); + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionManager.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionManager.java new file mode 100644 index 0000000000..dc24595686 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.github.chaoswang.learning.java.downloader.api; + +public interface ConnectionManager { + /** + * һurl , һ + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/DownloadListener.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/DownloadListener.java new file mode 100644 index 0000000000..113a2dbf93 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.github.chaoswang.learning.java.downloader.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionImpl.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionImpl.java new file mode 100644 index 0000000000..d3cd269ee1 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionImpl.java @@ -0,0 +1,73 @@ +package com.github.chaoswang.learning.java.downloader.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Arrays; + +import com.github.chaoswang.learning.java.downloader.api.Connection; + +public class ConnectionImpl implements Connection{ + + private HttpURLConnection conn; + private InputStream is; + + public ConnectionImpl(String url){ + initConn(url); + } + + private void initConn(String url){ + try{ + URL httpUrl = new URL(url); + conn = (HttpURLConnection)httpUrl.openConnection(); + conn.setConnectTimeout(3 * 1000); + conn.connect(); + is = conn.getInputStream(); + }catch(Exception e){ + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + //˼ǣܶ1024Ҳܲ1024 + byte[] buffer = new byte[1024]; + is.skip(startPos); + //߳Ҫصֽ + int currentSectionLength = endPos - startPos + 1; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int len = 0; + int hasRead = 0; + while((len < currentSectionLength) && ((hasRead = is.read(buffer)) != -1)) { + bos.write(buffer, 0, hasRead); + len += hasRead; + } + bos.close(); + is.close(); + //bytesܱcurrentSectionLengthԶ࣬ȡ + byte[] downloadedBytes = bos.toByteArray(); + byte[] needToDownload = Arrays.copyOf(downloadedBytes, currentSectionLength); + return needToDownload; + } + + @Override + public int getContentLength() { + int length = conn.getContentLength(); + System.out.println("length:" + length); + return length; + } + + @Override + public void close() { + try { + if(is != null){ + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionManagerImpl.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..45302694d3 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionManagerImpl.java @@ -0,0 +1,23 @@ +package com.github.chaoswang.learning.java.downloader.impl; + +import com.github.chaoswang.learning.java.downloader.api.Connection; +import com.github.chaoswang.learning.java.downloader.api.ConnectionException; +import com.github.chaoswang.learning.java.downloader.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + Connection conn = null; + if (url.startsWith("http")){ + conn = new ConnectionImpl(url); + }else if(url.startsWith("ftp")){ + //TODO + } + if(conn == null){ + throw new ConnectionException("Failed to get conneciton."); + } + return conn; + } + +} \ No newline at end of file diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/ClassFileLoader.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/ClassFileLoader.java new file mode 100644 index 0000000000..1b0b8f1514 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/ClassFileLoader.java @@ -0,0 +1,24 @@ +package com.github.chaoswang.learning.java.jvm; + +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + return null; + + } + + public void addClassPath(String path) { + + } + + public String getClassPath() { + return null; + } + +} diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrame.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrame.java new file mode 100644 index 0000000000..01bf2a7333 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrame.java @@ -0,0 +1,151 @@ +package com.github.chaoswang.learning.java.linkedlist; + +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + } + + private int capacity; + + private int currentSize; + private Node first;// ͷ + private Node last;// β + + public LRUPageFrame(int capacity) { + this.currentSize = 0; + this.capacity = capacity; + + } + + /** + * ȡж + * + * @param key + * @return + */ + public void access(int pageNum) { + + Node node = find(pageNum); + // ڸöдڣ ᵽͷ + if (node != null) { + + moveExistingNodeToHead(node); + + } else { + + node = new Node(); + node.pageNum = pageNum; + + // ǷѾС. + if (currentSize >= capacity) { + removeLast(); + + } + + addNewNodetoHead(node); + + } + } + + private void addNewNodetoHead(Node node) { + + if (isEmpty()) { + + node.prev = null; + node.next = null; + first = node; + last = node; + + } else { + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + this.currentSize++; + } + + private Node find(int data) { + + Node node = first; + while (node != null) { + if (node.pageNum == data) { + return node; + } + node = node.next; + } + return null; + + } + + /** + * ɾβڵ ʾ ɾʹõĻ + */ + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev; + this.currentSize--; + } + + /** + * ƶͷʾڵʹù + * + * @param node + */ + private void moveExistingNodeToHead(Node node) { + + if (node == first) { + + return; + } else if (node == last) { + // ǰڵβ Ҫŵͷ + Node prevNode = node.prev; + prevNode.next = null; + last.prev = null; + last = prevNode; + + } else { + // node м䣬 node ǰڵ + Node prevNode = node.prev; + prevNode.next = node.next; + + Node nextNode = node.next; + nextNode.prev = prevNode; + + } + + node.prev = null; + node.next = first; + first.prev = node; + first = node; + + } + + private boolean isEmpty() { + return (first == null) && (last == null); + } + + 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/group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LinkedList.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LinkedList.java new file mode 100644 index 0000000000..3f721d4793 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LinkedList.java @@ -0,0 +1,287 @@ +package com.github.chaoswang.learning.java.linkedlist; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.NoSuchElementException; +import java.util.Stack; + +import com.github.chaoswang.learning.java.array.ArrayUtil; + +public class LinkedList { + //޸IJҪάsize + private int size = 0; + //漰βڵʱҪάheadtailָ + private Node head = null; + private Node tail = null; + + // + public void add(E element){ + Node tmp = new Node(element, null); + if(tail == null){ + head = tmp; + }else{ + tail.next = tmp;; + } + tail = tmp; + size++; + } + + public void add(int index, E element){ + if(index < 0 || index > size){ + throw new IndexOutOfBoundsException(); + } + if(index == size){ + add(element); + return; + }else if(index == 0){ + addFirst(element); + return; + } + Node tmpBefore = getNode(index -1); + Node tmpAfter = getNode(index); + Node tmp = new Node(element, tmpAfter); + tmpBefore.next = tmp; + size++; + } + + public void addFirst(E element){ + Node tmp = new Node(element, null); + if(head != null){ + tmp.next = head; + }else{ + tail = tmp; + } + head = tmp; + size++; + } + + public E removeFirst(){ + if(size <= 0){ + throw new NoSuchElementException(); + } + Node tmp = head; + head = head.next; + size--; + if(size == 0){ + tail = null; + } + return (E)tmp.element; + } + + // + public E remove(int index) { + if(index < 0 || index >= size()){ + throw new IndexOutOfBoundsException(); + } + if(index == 0){ + return removeFirst(); + } + Node tmpBefore = this.getNode(index-1); + Node tmp = this.getNode(index); + Node tmpNext = this.getNode(index+1); + tmpBefore.next = tmpNext; + if(index == size - 1){ + tail = tmpBefore; + } + size--; + if(size == 0){ + tail = null; + } + return (E)tmp.element; + } + + // + public E get(int index){ + return (E)this.getNode(index).element; + } + + public int size() { + return size; + } + + @Override + public String toString() { + if(head == null){ + return "[]" + ", head:"+head+", tail:"+tail; + } + StringBuffer sb = new StringBuffer("["); + Node tmp = head; + while(tmp != null){ + sb.append(tmp.element.toString()); + sb.append("("); + if(tmp.next!=null){ + sb.append(tmp.next.element.toString()); + } + sb.append(")"); + sb.append(","); + + tmp = tmp.next; + } + String returnStr = sb.toString(); + returnStr = returnStr.substring(0, returnStr.length()-1); + return returnStr + "]" + ", head:"+head+", tail:"+tail; + } + + private Node getNode(int index) { + Node tmp = head; + for(int i=0;i7->10 , úΪ 10->7->3 + */ + public void reverse(){ + Stack stackCache = new Stack(); + Node currentNode = head; + for(int i=0;i5->7->8 , ɾԺֵΪ 7->8 + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + */ + public void removeFirstHalf(){ + Node halfNodeBefore = getNode((size/2)-1); + head = halfNodeBefore.next; + halfNodeBefore.next = null; + } + + /** + * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * list = 2->5->7->8->10 ,remove(2,2)ԺֵΪ2->5->10 + * @param i + * @param length + */ + public void remove(int i, int length){ + Node nodePointer = getNode(i-1); + Node nodeTargetBefore = getNode(i-1+length); + nodePointer.next = nodeTargetBefore.next; + nodeTargetBefore.next = null; + } + + /** + * ٶǰ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){ + ArrayList cache = new ArrayList(); + for(int i=0;i101->201->301->401->501->601->701 + * listB = [11,201,501,701] + * صĽӦ[101,301,401,601] + * @param list + */ + public void subtract(LinkedList list){ + HashSet set = new HashSet(); + for(int i=0;i101->201->301->401->501->601->701 + * listB = [11,201,801,901] + * صĽӦ[11,201] + * @param list + */ + public LinkedList intersection(LinkedList list){ + HashSet set = new HashSet(); + for(int i=0;i { +public class Stack { private int size = 0; private int initialSize; private Object[] elements = null;//ԸΪԼArrayListʵ - public MyStack(int initialSize){ + public Stack(int initialSize){ this.initialSize = initialSize; elements = new Object[initialSize]; } diff --git a/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java new file mode 100644 index 0000000000..d5d7ecc223 --- /dev/null +++ b/group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java @@ -0,0 +1,45 @@ +package com.github.chaoswang.learning.java.stack; + +public class StackUtil { + + /** + * ջеԪInteger, ջջ : 5,4,3,2,1 ø÷ ԪشΪ: 1,2,3,4,5 + * ע⣺ֻʹStackĻpush,pop,peek,isEmpty ʹһջ + */ + public static void reverse(Stack s) { + + } + + /** + * ɾջеijԪ ע⣺ֻʹStackĻpush,pop,peek,isEmpty ʹһջ + * + * @param o + */ + public static void remove(Stack s, Object o) { + + } + + /** + * ջȡlenԪ, ԭջԪرֲ ע⣺ֻʹStackĻpush,pop,peek,isEmpty + * ʹһջ + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + return null; + } + + /** + * ַs ܰЩַ ( ) [ ] { }, a,b,c... x,yz ʹöջַsеDzdzɶԳֵġ s = + * "([e{d}f])" , ַеdzɶԳ֣ ÷true s = "([b{x]y})", + * ַеŲdzɶԳֵģ ÷false; + * + * @param s + * @return + */ + public static boolean isValidPairs(String s) { + return false; + } + +} \ No newline at end of file diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedListTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedListTest.java deleted file mode 100644 index cdbbcf2812..0000000000 --- a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedListTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.github.chaoswang.learning.java.collection.myown; - -import org.junit.Assert; -import org.junit.Test; - -public class MyLinkedListTest { - - @Test - public void testAdd(){ - MyLinkedList myList = new MyLinkedList(); - myList.add("1"); - myList.add("2"); - myList.add("3"); - Assert.assertEquals(3, myList.size()); - myList.add("4"); - Assert.assertEquals(4, myList.size()); - System.out.println(myList); - String str = myList.get(2); - Assert.assertEquals("3", str); - - } - - @Test - public void testInsert(){ - MyLinkedList myList = new MyLinkedList(); - myList.add("1"); - myList.add("2"); - myList.add("4"); - String str = myList.get(2); - Assert.assertEquals("4", str); - myList.add(2,"3"); - str = myList.get(2); - Assert.assertEquals("3", str); - } - - @Test - public void testAddFirst(){ - MyLinkedList myList = new MyLinkedList(); - myList.add("2"); - myList.add("3"); - myList.add("4"); - System.out.println(myList); - Assert.assertEquals("2", myList.get(0)); - myList.addFirst("1"); - Assert.assertEquals("1", myList.get(0)); - System.out.println(myList); - } - - @Test - public void testRemoveFirst(){ - MyLinkedList myList = new MyLinkedList(); - myList.add("1"); - myList.add("2"); - myList.add("3"); - myList.add("4"); - String str = myList.removeFirst(); - System.out.println(myList); - Assert.assertEquals("1", str); - Assert.assertEquals("2", myList.get(0)); - } - - @Test - public void testRemove(){ - MyLinkedList myList = new MyLinkedList(); - myList.add("1"); - myList.add("2"); - myList.add("3"); - myList.add("4"); - String str = myList.remove(2); - Assert.assertEquals("3", str); - str = myList.get(2); - Assert.assertEquals("4", str); - Assert.assertEquals(3, myList.size()); - } - -} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyStackTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyStackTest.java index 4ae0c84989..71336bd868 100644 --- a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyStackTest.java +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyStackTest.java @@ -7,6 +7,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; +import com.github.chaoswang.learning.java.stack.Stack; + public class MyStackTest { @Rule @@ -14,7 +16,7 @@ public class MyStackTest { @Test public void testPushAndPop(){ - MyStack myStack = new MyStack(3); + Stack myStack = new Stack(3); myStack.push("1"); myStack.push("2"); myStack.push("3"); @@ -27,7 +29,7 @@ public void testPushAndPop(){ @Test public void testPopWhenQueueIsEmpty(){ thrown.expect(EmptyStackException.class); - MyStack myStack = new MyStack(3); + Stack myStack = new Stack(3); myStack.push("1"); myStack.pop(); //Ƴ쳣 @@ -36,7 +38,7 @@ public void testPopWhenQueueIsEmpty(){ @Test public void testSearch(){ - MyStack myStack = new MyStack(3); + Stack myStack = new Stack(3); myStack.push("1"); myStack.push("2"); myStack.push("3"); diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/downloader/FileDownloaderTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/downloader/FileDownloaderTest.java new file mode 100644 index 0000000000..8b4020d8c0 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/downloader/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.github.chaoswang.learning.java.downloader; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.chaoswang.learning.java.downloader.api.ConnectionManager; +import com.github.chaoswang.learning.java.downloader.api.DownloadListener; +import com.github.chaoswang.learning.java.downloader.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://desk.fd.zol-img.com.cn/t_s2560x1600c5/g5/M00/02/09/ChMkJ1bKzeqIXxeTACOMfnPW4wsAALJFgHb1LMAI4yW109.jpg"; + + FileDownloader downloader = new FileDownloader(url, 1); + + + 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/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java new file mode 100644 index 0000000000..25f2d1afb8 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java @@ -0,0 +1,76 @@ +package com.github.chaoswang.learning.java.jvm; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + 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 < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + +} \ No newline at end of file diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/EmployeeV1.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/EmployeeV1.java new file mode 100644 index 0000000000..1855f34274 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.github.chaoswang.learning.java.jvm; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrameTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrameTest.java new file mode 100644 index 0000000000..eb0700e609 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrameTest.java @@ -0,0 +1,33 @@ +package com.github.chaoswang.learning.java.linkedlist; + +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()); + frame.access(5); + Assert.assertEquals("5,4,0", frame.toString()); + + } + +} \ No newline at end of file diff --git a/group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LinkedListTest.java b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LinkedListTest.java new file mode 100644 index 0000000000..1b47f86544 --- /dev/null +++ b/group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LinkedListTest.java @@ -0,0 +1,239 @@ +package com.github.chaoswang.learning.java.linkedlist; + +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.Test; + +import com.github.chaoswang.learning.java.linkedlist.LinkedList; + +public class LinkedListTest { + + @Test + public void testAdd(){ + LinkedList myList = new LinkedList(); + myList.add("1"); + myList.add("2"); + myList.add("3"); + System.out.println(myList); + Assert.assertEquals(3, myList.size()); + myList.add("4"); + System.out.println(myList); + Assert.assertEquals(4, myList.size()); + String str = myList.get(2); + Assert.assertEquals("3", str); + System.out.println(myList); + } + + @Test + public void testInsert(){ + LinkedList myList = new LinkedList(); + myList.add("2"); + myList.add("4"); + System.out.println(myList); + myList.add(0,"1"); + System.out.println(myList); + String str = myList.get(2); + Assert.assertEquals("4", str); + myList.add(2,"3"); + str = myList.get(2); + System.out.println(myList); + Assert.assertEquals("3", str); + } + + @Test + public void testAddFirst(){ + LinkedList myList = new LinkedList(); + myList.add("2"); + myList.add("3"); + myList.add("4"); + System.out.println(myList); + Assert.assertEquals("2", myList.get(0)); + myList.addFirst("1"); + Assert.assertEquals("1", myList.get(0)); + System.out.println(myList); + } + + @Test + public void testRemoveFirst(){ + LinkedList myList = new LinkedList(); + myList.add("1"); + myList.add("2"); + myList.add("3"); + myList.add("4"); + String str = myList.removeFirst(); + Assert.assertEquals("1", str); + Assert.assertEquals("2", myList.get(0)); + System.out.println(myList); + } + + @Test + public void testRemove(){ + LinkedList myList = new LinkedList(); + myList.add("1"); + myList.add("2"); + myList.add("3"); + myList.add("4"); + String str = myList.remove(2); + System.out.println(myList); + Assert.assertEquals("3", str); + str = myList.get(2); + Assert.assertEquals("4", str); + Assert.assertEquals(3, myList.size()); + System.out.println(myList); + } + + @Test + public void testRemoveAll(){ + LinkedList myList = new LinkedList(); + myList.add("1"); + myList.add("2"); + System.out.println(myList); + String str = myList.removeFirst(); + System.out.println(myList); + Assert.assertEquals("1", str); + str = myList.removeFirst(); + Assert.assertEquals("2", str); + Assert.assertEquals(0, myList.size()); + System.out.println(myList); + } + + /** + * Ѹ + * Ϊ 3->7->10 , úΪ 10->7->3 + */ + @Test + public void testReverse(){ + LinkedList myList = new LinkedList(); + myList.add("1"); + myList.add("3"); + myList.add("5"); + myList.add("7"); + myList.add("9"); + System.out.println(myList); + myList.reverse(); + System.out.println(myList); + } + + /** + * ɾһǰ벿 + * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + */ + @Test + public void testRemoveFirstHalf(){ + LinkedList myList = new LinkedList(); + myList.add("2"); + myList.add("5"); + myList.add("7"); + myList.add("8"); + myList.add("10"); + System.out.println(myList); + myList.removeFirstHalf(); + System.out.println(myList); + } + + /** + * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * list = 2->5->7->8->10 ,remove(2,2)ԺֵΪ2->5->10 + * @param i + * @param length + */ + @Test + public void testRemoveBySpecificLength(){ + LinkedList myList = new LinkedList(); + myList.add("2"); + myList.add("5"); + myList.add("7"); + myList.add("8"); + myList.add("10"); + System.out.println(myList); + myList.remove(2,2); + System.out.println(myList); + } + + /** + * ٶǰlistBе + * ӵǰȡЩlistBָԪ + * 統ǰ = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * صĽӦ[101,301,401,601] + * @param list + */ + @Test + public void testGetElements(){ + LinkedList myList = new LinkedList(); + myList.add("11"); + myList.add("101"); + myList.add("201"); + myList.add("301"); + myList.add("401"); + myList.add("501"); + myList.add("601"); + myList.add("701"); + System.out.println(myList); + LinkedList testList = new LinkedList(); + testList.add(1); + testList.add(3); + testList.add(4); + testList.add(6); + System.out.println(Arrays.toString(myList.getElements(testList))); + } + + /** + * ֪еԪֵУԵ洢ṹ + * ӵǰɾlistBгֵԪ + * 統ǰ = 11->101->201->301->401->501->601->701 + * listB = [11,201,501,701] + * صĽӦ[101,301,401,601] + * @param list + */ + @Test + public void subtract(){ + LinkedList myList = new LinkedList(); + myList.add("11"); + myList.add("101"); + myList.add("201"); + myList.add("301"); + myList.add("401"); + myList.add("501"); + myList.add("601"); + myList.add("701"); + System.out.println(myList); + LinkedList testList = new LinkedList(); + testList.add(11); + testList.add(201); + testList.add(501); + testList.add(701); + myList.subtract(testList); + System.out.println(myList); + } + + /** + * 赱ǰͲlistָԪֵУͬһеԪֵͬ + * ҪCԪΪǰlistԪصĽұCеԪֵ + * 統ǰ = 11->101->201->301->401->501->601->701 + * listB = [11,201,801,901] + * صĽӦ[11,201] + * @param list + */ + @Test + public void intersection(){ + LinkedList myList = new LinkedList(); + myList.add("11"); + myList.add("101"); + myList.add("201"); + myList.add("301"); + myList.add("401"); + myList.add("501"); + myList.add("601"); + myList.add("701"); + System.out.println(myList); + LinkedList testList = new LinkedList(); + testList.add(11); + testList.add(201); + testList.add(801); + testList.add(901); + System.out.println(myList.intersection(testList)); + } +} diff --git a/group06/547958234/src/com/coderising/array/ArrayUtil.java b/group06/547958234/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..2f0d91bad1 --- /dev/null +++ b/group06/547958234/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,163 @@ +package com.coderising.array; + + +import sun.reflect.generics.tree.VoidDescriptor; + +import java.awt.event.InputMethodListener; +import java.awt.image.AreaAveragingScaleFilter; + +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) { + int mid; + if (origin.length % 2 == 0) { + mid = origin.length / 2 - 1; + } else { + mid = origin.length / 2; + } + for (int i = 0; i <= mid; i++) { + int 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) { + int size = 0; + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] != 0) { + size++; + } + } + int[] newArray = new int[size]; + int j = 0; + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] != 0) newArray[j++] = oldArray[i]; + } + return newArray; + } + + /** + * 给定两个已经排序好的整形数组, 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) { + int[] mergedArray = new int[array1.length + array2.length]; + int i = 0; + int j = 0; + int k = 0; + while (i < array1.length) { + while (j < array2.length) { + if (array1[i] > array2[j]) { + mergedArray[k++] = array2[j++]; + } else { + mergedArray[k++] = array1[i++]; + } + } + } + return mergedArray; + } + + /** + * 把一个已经存满数据的数组 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) { + int newSize = oldArray.length + size; + int[] newArray = new int[newSize]; + for (int i = 0; i < oldArray.length; i++) { + newArray[i] = oldArray[i]; + } + 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 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) { + String s = ""; + for (int i = 0; i < array.length; i++) { + if (i != array.length - 1) { + s += array[i] + seperator; + } + } + s += array[array.length -1]; + return s; + } + + public static void main(String[] args) { + int[] array = {1, 2, 3, 4, 0, 1, 0, 2}; + reverseArray(array); + for (int i = 0; i < array.length; i++) System.out.print(array[i]); + int[] newArray = removeZero(array); + for (int i = 0; i < newArray.length; i++) System.out.print(newArray[i]); + } +} diff --git a/group06/547958234/src/com/coderising/download/DownloadThread.java b/group06/547958234/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..1456314140 --- /dev/null +++ b/group06/547958234/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,20 @@ +package com.coderising.download; + +import com.coderising.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/group06/547958234/src/com/coderising/download/FileDownloader.java b/group06/547958234/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..f5d7999eb4 --- /dev/null +++ b/group06/547958234/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,73 @@ +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; + + +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/group06/547958234/src/com/coderising/download/FileDownloaderTest.java b/group06/547958234/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..8171ee5763 --- /dev/null +++ b/group06/547958234/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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://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/group06/547958234/src/com/coderising/download/api/Connection.java b/group06/547958234/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..9710e270e1 --- /dev/null +++ b/group06/547958234/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/group06/547958234/src/com/coderising/download/api/ConnectionException.java b/group06/547958234/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..8dbfe95dda --- /dev/null +++ b/group06/547958234/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group06/547958234/src/com/coderising/download/api/ConnectionManager.java b/group06/547958234/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..fb44ede457 --- /dev/null +++ b/group06/547958234/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/group06/547958234/src/com/coderising/download/api/DownloadListener.java b/group06/547958234/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..4cd0b3eab1 --- /dev/null +++ b/group06/547958234/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/group06/547958234/src/com/coderising/download/impl/ConnectionImpl.java b/group06/547958234/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..32f03efdc7 --- /dev/null +++ b/group06/547958234/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,27 @@ +package com.coderising.download.impl; + +import java.io.IOException; + +import com.coderising.download.api.Connection; + +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/group06/547958234/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group06/547958234/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..046f7c49a4 --- /dev/null +++ b/group06/547958234/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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 null; + } + +} diff --git a/group06/547958234/src/com/coderising/litestruts/LoginAction.java b/group06/547958234/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group06/547958234/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/group06/547958234/src/com/coderising/litestruts/Struts.java b/group06/547958234/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..85e2e22de3 --- /dev/null +++ b/group06/547958234/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,34 @@ +package com.coderising.litestruts; + +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/group06/547958234/src/com/coderising/litestruts/StrutsTest.java b/group06/547958234/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group06/547958234/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/group06/547958234/src/com/coderising/litestruts/View.java b/group06/547958234/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group06/547958234/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group06/547958234/src/com/coderising/litestruts/struts.xml b/group06/547958234/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..0582b7d4ea --- /dev/null +++ b/group06/547958234/src/com/coderising/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/group06/949319266/Test/src/com/ecust/test/GArrayList.java b/group06/949319266/Test/src/com/ecust/test/GArrayList.java new file mode 100644 index 0000000000..e0282ec416 --- /dev/null +++ b/group06/949319266/Test/src/com/ecust/test/GArrayList.java @@ -0,0 +1,148 @@ +package com.ecust.test; +import java.util.*; +public class GArrayList implements GList { + + private int size; + private Object[] dataArray= new Object[0]; + + @Override + public int size() { + return this.size; + } + + @Override + public boolean isEmpty() { + return this.size == 0; + } + + @Override + public boolean contains(Object o) { + for(Object obj:dataArray) { + if(Objects.equals(obj, o)) + return true; + } + return false; + } + + @Override + public Object[] toArray() { + Object[] array = new Object[size]; + System.arraycopy(dataArray, 0, array, 0, size); + return array; + } + + @Override + public boolean add(T t) { + ensureCapacity(size+1); + dataArray[size] = t; + size++; + return true; + } + + + + @Override + public boolean remove(T t) { + int index = indexof(t); + if(index < 0) { + return false; + } + System.arraycopy(dataArray, index+1, dataArray, index, size-1-index); + dataArray[size-1] = null; + size--; + return true; + } + + @Override + public void clear() { + dataArray = new Object[size]; + size = 0; + } + + @Override + public T get(int index) { + if(index < -1 || index >= size) { + throw new IndexOutOfBoundsException(); + } + return (T)dataArray[index]; + } + + @Override + public T set(int index, T t) { + if(index < -1 || index >= size) { + throw new IndexOutOfBoundsException(); + } + dataArray[index] = t; + return t; + } + + @Override + public void add(int index, T t) { + if(index < -1 || index >= size) { + throw new IndexOutOfBoundsException(); + } + ensureCapacity(size+1); + System.arraycopy(dataArray, index, dataArray, index+1, size-index); + dataArray[index] = t; + size++; + } + + @Override + public T remove(int index) { + if(index < -1 || index >= size) { + throw new IndexOutOfBoundsException(); + } + T element = (T)dataArray[index]; + System.arraycopy(dataArray, index+1, dataArray, index, size-1-index); + dataArray[size-1] = null; + size--; + return element; + } + + @Override + public int indexof(T t) { + for(int i = 0;i iterator() { + return new ArrayListIterator(this); + } + private void ensureCapacity(int i) { + if(i > dataArray.length) { + int newlength = Math.max(i, dataArray.length*2); + Object[] newDataArray = new Object[newlength]; + System.arraycopy(dataArray, 0, newDataArray, 0, dataArray.length); + dataArray = newDataArray; + } + } + private class ArrayListIterator implements GIterator { + private int position; + private GArrayList list; + + ArrayListIterator(GArrayList list) { + this.list = list; + } + + @Override + public boolean hasNext() { + + return position < list.size; + } + + @Override + public T next() { + if(hasNext()) { + return list.get(position++); + } + return null; + } + + } + +} diff --git a/group06/949319266/Test/src/com/ecust/test/GIterator.java b/group06/949319266/Test/src/com/ecust/test/GIterator.java new file mode 100644 index 0000000000..08ae05f395 --- /dev/null +++ b/group06/949319266/Test/src/com/ecust/test/GIterator.java @@ -0,0 +1,6 @@ +package com.ecust.test; + +public interface GIterator { + boolean hasNext(); + T next(); +} diff --git a/group06/949319266/Test/src/com/ecust/test/GList.java b/group06/949319266/Test/src/com/ecust/test/GList.java new file mode 100644 index 0000000000..00098b2d55 --- /dev/null +++ b/group06/949319266/Test/src/com/ecust/test/GList.java @@ -0,0 +1,18 @@ +package com.ecust.test; + +public interface GList { + int size(); + boolean isEmpty(); + boolean contains(Object o); + Object[] toArray(); + boolean add(T t); + boolean remove(T t); + void clear(); + T get (int index); + T set (int index,T t); + void add(int index,T t); + T remove(int index); + int indexof(T t); + GIterator iterator(); + +} diff --git a/group06/1378560653/src/com/coding/basic/LinkedList.java b/group06/949319266/homework/src/com/coding/basic/LinkedList.java similarity index 77% rename from group06/1378560653/src/com/coding/basic/LinkedList.java rename to group06/949319266/homework/src/com/coding/basic/LinkedList.java index d7b4775f35..b891cdd2d6 100644 --- a/group06/1378560653/src/com/coding/basic/LinkedList.java +++ b/group06/949319266/homework/src/com/coding/basic/LinkedList.java @@ -1,342 +1,680 @@ package com.coding.basic; +import java.util.Iterator; public class LinkedList implements List { + + private Node head; + private int size; + + private static class Node { + Object data; + Node next; + + public Node(Object data){ + this.data = data; + this.next = null; + } + } + + public LinkedList(){ + this.head = new Node(null); + this.size = 0; + } + + public void add(Object o){ + Node newNode = new Node(o); + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + } + + pNode.next = newNode; + size++; + } + public void add(int index , Object o){ + checkIndex(index); + + Node newNode = new Node(o); + Node node = new Node(null); + Node pNode = head; + for(int i = 0; i < index; i++){ + node = pNode; + pNode = pNode.next; + } + + node.next = newNode; + newNode.next = pNode; + size++; + } + public Object get(int index){ + checkIndex(index); + + Node pNode = head; + for(int i = 0; i < index; i++){ + pNode = pNode.next; + } + + return pNode.data; + } + public Object remove(int index){ + checkIndex(index); + if(size == 0){ + return null; + } + + Node node = new Node(null); + Node pNode = head; + for(int i = 0; i < index; i++){ + node = pNode; + pNode = pNode.next; + } + node.next = pNode.next; + size--; + + return pNode; + } + + public int size(){ + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + size++; + } + return size; + } + + public void addFirst(Object o){ + if(size == 0){ + head.data = o; + } + + Node newNode = new Node(o); + Node pNode = head; + head = newNode; + newNode.next = pNode.next; + size++; + } + public void addLast(Object o){ + if(size == 0){ + head.data = o; + } + + Node newNode = new Node(o); + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + } + pNode.next = newNode; + newNode.next = null; + size++; + } + public Object removeFirst(){ + if(size == 0){ + return null; + } + + Node pNode = head; + head = pNode.next; + head.next = pNode.next.next; + size--; + return pNode; + } + public Object removeLast(){ + if(size == 0){ + return null; + } + + Node pNode = head; + Node node = new Node(null); + while(pNode.next != null){ + node = pNode; + pNode = pNode.next; + } + + node.next = null; + size--; + return pNode; + } + public Iterator iterator(){ + return new LinkedListIterator(); + } + - //注意这一个问题 + + //עһ + public class LinkedListIterator implements Iterator { + private int position; + + @Override + public boolean hasNext() { + return position < size(); + } + + @Override + public Object next() { + if(hasNext()){ + return get(position++); + } + return null; + } + + } + + public void checkIndex(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + } + + /** - * 把该链表逆置 - * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + + * Ѹ + + * Ϊ 3->7->10 , úΪ 10->7->3 + */ + public void reverse(Node head){ + if(head.next == null || head.next.next == null){ + return; + } + + Node p = head.next; + Node q = head.next.next; + Node t = null; + + while(q.next != null){ + t = q.next; + q.next = p; + p = q; + q = t; + } + - head.next.next = null;//设置链表尾部 - head.next = p;//设置链表头部 + + head.next.next = null;//β + + head.next = p;//ͷ + } + + /** - * 删除一个单链表的前半部分 - * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 - * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + * ɾһǰ벿 + + * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 + + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + + */ + public void removeFirstHalf(){ + if(size == 0 || head.next == null || head.next.next == null){ + return; + } + + Node pNode = head; + Node node = null; + for(int i = 0; i < size/2; i++){ + node = pNode; + pNode = pNode.next; + } + + if(size %2 == 0){ + head.next = pNode; + }else{ + head.next = node; + } + } + + /** - * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + + * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * @param i + * @param length + */ + public void remove(int i, int length){ + if(size == 0 || head.next == null){ + return; + } + + for(int k = i; k < i + length; k++){ + checkIndex(k); + remove(k); + } + } + /** - * 假定当前链表和list均包含已升序排列的整数 - * 从当前链表中取出那些list所指定的元素 - * 例如当前链表 = 11->101->201->301->401->501->601->701 + + * ٶǰlistе + + * ӵǰȡЩlistָԪ + + * 統ǰ = 11->101->201->301->401->501->601->701 + * list = 1->3->4->6 - * 返回的结果应该是[101,301,401,601] + + * صĽӦ[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list.size == 0 || list == null){ + return new int[0]; + } + + int[] array = new int[list.size]; + int k = 0; + for(int i = 0; i < list.size; i++){ + int index = (int) list.get(i); + array[k] = (int) get(index); + } + return array; + } + + /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 从当前链表中中删除在list中出现的元素 + + * ֪еԪֵУԵ洢ṹ + + * ӵǰɾlistгֵԪ + + * @param list + */ + + public void subtract(LinkedList list,LinkedList oldList){ + if(oldList == null || oldList.size ==0 || list == null || list.size == 0){ + return; + } + + for(int i = 0; i < oldList.size; i++){ + for(int j = 0; j < list.size; j++){ + if(list.get(j) == oldList.get(i)){ + oldList.remove(i); + } + } + } + } + + /** - * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + + * ֪ǰеԪֵУԵ洢ṹ + + * ɾֵͬĶԪأʹòԱԪصֵͬ + */ + public void removeDuplicateValues(LinkedList list){ + if(list == null || list.size == 0){ + return; + } + + int count = 0; + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + count++; + if(pNode.data == pNode.next.data){ + list.remove(count+1); + } + } + } + + /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + + * ֪еԪֵУԵ洢ṹ + + * дһЧ㷨ɾֵminСmaxԪأдԪأ + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(size == 0){ + return; + } + + int count = 0; + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + count++; + if(min < (int)pNode.data || (int)pNode.data < max){ + remove(count); + } + } + } + + /** - * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) - * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + + * 赱ǰͲlistָԪֵУͬһеԪֵͬ + + * ҪCԪΪǰlistԪصĽұCеԪֵ + * @param list + */ + public LinkedList intersection( LinkedList list){ + if(list.size == 0){ + return null; + } + + LinkedList listC = new LinkedList(); + Node p = head; + Node q = list.head; + + while(p.next != null){ + p = p.next; + while(q.next !=null){ + q = q.next; + if(p.data.equals(q.data)){ + listC.add(p); + } + } + } + return listC; + } -} + +} \ No newline at end of file diff --git a/group06/949319266/homework/src/com/coding/basic/List.java b/group06/949319266/homework/src/com/coding/basic/List.java new file mode 100644 index 0000000000..22573a2ced --- /dev/null +++ b/group06/949319266/homework/src/com/coding/basic/List.java @@ -0,0 +1,17 @@ +package com.coding.basic; + + + +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(); + +} \ No newline at end of file diff --git "a/group06/949319266/homework/src/\346\226\207\347\253\240\344\270\211" "b/group06/949319266/homework/src/\346\226\207\347\253\240\344\270\211" new file mode 100644 index 0000000000..9b7a0eadcc --- /dev/null +++ "b/group06/949319266/homework/src/\346\226\207\347\253\240\344\270\211" @@ -0,0 +1 @@ +http://blog.sina.com.cn/s/blog_c20b18280102x3ol.html \ No newline at end of file diff --git a/group06/949319266/homework003/src/DownloadThread.java b/group06/949319266/homework003/src/DownloadThread.java new file mode 100644 index 0000000000..3cb576e6a7 --- /dev/null +++ b/group06/949319266/homework003/src/DownloadThread.java @@ -0,0 +1,154 @@ + +import java.io.IOException; + +import java.io.RandomAccessFile; + +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 DownloadThread extends Thread { + + + + private int endPos; + + private int startPos; + + private String url; + + private String destFilePath; + + private ConnectionManager connManager; + + private DownloadListener downloadListener; + + + + public DownloadThread(ConnectionManager connManager, String url, int startPos, int endPos, String destFilePath, + + DownloadListener downloadListener) { + + + + this.url = url; + + this.endPos = endPos; + + this.startPos = startPos; + + this.connManager = connManager; + + this.destFilePath = destFilePath; + + this.downloadListener = downloadListener; + + } + + + + @Override + + public void run() { + + Connection conn = null; + + RandomAccessFile randomAccessFile = null; + + try { + + doLog("BIN"); + + conn = connManager.open(url, startPos, endPos); + + byte[] read = conn.read(startPos, endPos); + + String _filePath = destFilePath; + + if (_filePath == null || _filePath.length() == 0) { + + _filePath = conn.getFileName(); + + } + + randomAccessFile = new RandomAccessFile(_filePath, "rw"); + + randomAccessFile.seek(startPos); + + randomAccessFile.write(read); + + doLog("END"); + + } catch (IOException e) { + + doLog("EXP"); + + e.printStackTrace(); + + } catch (ConnectionException e) { + + doLog("EXP"); + + e.printStackTrace(); + + } finally { + + if (randomAccessFile != null) { + + try { + + randomAccessFile.close(); + + } catch (IOException e) { + + e.printStackTrace(); + + } + + } + + if (conn != null) { + + conn.close(); + + } + + if (downloadListener != null) { + + downloadListener.notifyFinished(); + + } + + } + + } + + + + private void doLog(String action) { + + System.out.println( + + "*********** " + action + + + " [" + + + startPos + + + "-" + + + endPos + + + "]" + + + " ***********"); + + } + +} diff --git a/group06/949319266/homework003/src/FileDownloader.java b/group06/949319266/homework003/src/FileDownloader.java new file mode 100644 index 0000000000..cf09f40351 --- /dev/null +++ b/group06/949319266/homework003/src/FileDownloader.java @@ -0,0 +1,158 @@ + +import java.util.concurrent.atomic.AtomicInteger; + +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 DownloadListener listener; + + + + private ConnectionManager cm; + + + + private AtomicInteger atomicInteger; + + + + public FileDownloader(String _url) { + + this.url = _url; + + atomicInteger = new AtomicInteger(); + + } + + + + /** + + * 在这里实现你的代码, 注意: 需要用多线程实现下载 + + * 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + + * (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方法 + + * + + * 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + + */ + + public void execute() { + + try { + + + + int threadCount = 5; + + int length = this.cm.getContentLength(this.url); + + for (int i = 0; i < threadCount; i++) { + + + + int threadLoadLength = length / threadCount; + + int startPos = threadLoadLength * i; + + int endPos; + + if (i != threadCount - 1) { + + endPos = threadLoadLength * (i + 1) - 1; + + } else { + + endPos = length - 1; + + } + + atomicInteger.getAndIncrement(); + + new DownloadThread(cm, this.url, startPos, endPos, null, new DownloadListener() { + + @Override + + public void notifyFinished() { + + if (atomicInteger.decrementAndGet() == 0) { + + if (FileDownloader.this.listener != null) { + + FileDownloader.this.listener.notifyFinished(); + + } + + } + + } + + }).start(); + + } + + } catch (ConnectionException e) { + + e.printStackTrace(); + + } + + } + + + + public void setConnectionManager(ConnectionManager ucm) { + + this.cm = ucm; + + } + + + + public DownloadListener getListener() { + + return this.listener; + + } + + + + public void setListener(DownloadListener listener) { + + this.listener = listener; + + } + +} diff --git a/group06/949319266/homework003/src/FileDownloaderTest.java b/group06/949319266/homework003/src/FileDownloaderTest.java new file mode 100644 index 0000000000..0587b33d53 --- /dev/null +++ b/group06/949319266/homework003/src/FileDownloaderTest.java @@ -0,0 +1,107 @@ +import static org.junit.Assert.*; + +import org.junit.Test; + +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 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489721424&di=1fda6467501ab1d5e5bff43e801d14ee&imgtype=jpg&er=1&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201507%2F30%2F20150730163204_A24MX.thumb.700_0.jpeg"; + + //String url = "http://apache.fayea.com/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz"; + + + + 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/group06/949319266/homework003/src/com/coderising/download/api/Connection.java b/group06/949319266/homework003/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..7dd9910463 --- /dev/null +++ b/group06/949319266/homework003/src/com/coderising/download/api/Connection.java @@ -0,0 +1,63 @@ +package com.coderising.download.api; + +import java.io.IOException; + + + +public interface Connection { + + /** + + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + + * + + * @param startPos 开始位置, 从0开始 + + * @param endPos 结束位置 + + * @return 读取的字节数组 + + */ + + byte[] read(int startPos, int endPos) throws IOException; + + + + /** + + * 得到数据内容的长度 + + * + + * @return 数据内容长度 + + */ + + int getContentLength(); + + + + /** + + * 关闭连接 + + */ + + void close(); + + + + /** + + * 获取下载文件的文件名 + + * + + * @return 文件名 + + */ + + String getFileName(); + +} \ No newline at end of file diff --git a/group06/949319266/homework003/src/com/coderising/download/api/ConnectionException.java b/group06/949319266/homework003/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..49cb949c13 --- /dev/null +++ b/group06/949319266/homework003/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,19 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(Exception e) { + + super(e); + + } + + + + public ConnectionException(String msg) { + + super(msg); + + } + +} \ No newline at end of file diff --git a/group06/949319266/homework003/src/com/coderising/download/api/ConnectionManager.java b/group06/949319266/homework003/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ab72224242 --- /dev/null +++ b/group06/949319266/homework003/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,14 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + + */ + Connection open(String url, int startPos, int endPos) throws ConnectionException; + /** + * 获取文件长度 + */ + int getContentLength(String url) throws ConnectionException; + +} diff --git a/group06/949319266/homework003/src/com/coderising/download/api/DownloadListener.java b/group06/949319266/homework003/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..c5aa8c6b7d --- /dev/null +++ b/group06/949319266/homework003/src/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,7 @@ +package com.coderising.download.api; + +public interface DownloadListener { + + void notifyFinished(); + +} diff --git a/group06/949319266/homework003/src/com/coderising/download/impl/ConnectionImpl.java b/group06/949319266/homework003/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..e08611ebfb --- /dev/null +++ b/group06/949319266/homework003/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,186 @@ +package com.coderising.download.impl; + +import java.io.IOException; + +import com.coderising.download.api.Connection; + +import java.io.ByteArrayOutputStream; + +import java.io.IOException; + +import java.io.InputStream; + +import java.net.HttpURLConnection; + + + + +public class ConnectionImpl implements Connection { + + + + private static final int BUFFER_SIZE = 4096; + + private HttpURLConnection httpConn; + + private String fileUrl; + + private InputStream inputStream; + + + + public ConnectionImpl(HttpURLConnection httpConn, String fileUrl) { + + this.httpConn = httpConn; + + this.fileUrl = fileUrl; + + } + + + + @Override + + public byte[] read(int startPos, int endPos) throws IOException { + + if (endPos < startPos) { + + throw new IllegalArgumentException("argument endPos[" + endPos + "] less than startPos[" + startPos + "]"); + + } + + int bytesNeed2Read = endPos - startPos + 1; + + if (bytesNeed2Read > getContentLength()) { + + throw new IllegalArgumentException( + + "endPos[" + endPos + "] is bigger than content length[" + getContentLength() + "]"); + + } + + + + inputStream = httpConn.getInputStream(); + + + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + byte[] buffer = new byte[Math.min(bytesNeed2Read, BUFFER_SIZE)]; + + int read; + + + + long startTime = System.currentTimeMillis(); + + final long progressInterval = 2000; + + while ((read = inputStream.read(buffer)) != -1) { + + byteArrayOutputStream.write(buffer, 0, read); + + + + if (System.currentTimeMillis() - startTime > progressInterval) { + + startTime = System.currentTimeMillis(); + + System.out.println(String.format(Thread.currentThread().getName() + + + " [%.2f%%]", byteArrayOutputStream.size() * 100.0 / bytesNeed2Read) + + ); + + } + + } + + System.out.println(String.format(Thread.currentThread().getName() + " [%.2f%%]", 100.0)); + + System.out.println("bytes read: " + byteArrayOutputStream.size()); + + + + return byteArrayOutputStream.toByteArray(); + + } + + + + @Override + + public int getContentLength() { + + if (httpConn != null) { + + return httpConn.getContentLength(); + + } + + return 0; + + } + + + + @Override + + public void close() { + + if (inputStream != null) { + + try { + + inputStream.close(); + + } catch (IOException e) { + + e.printStackTrace(); + + } + + } + + if (httpConn != null) { + + httpConn.disconnect(); + + } + + } + + + + @Override + + public String getFileName() { + + String disposition = httpConn.getHeaderField("Content-Disposition"); + + if (disposition != null) { + + // extracts file name from header field + + int index = disposition.indexOf("filename="); + + if (index > 0) { + + return disposition.substring(index + 10, + + disposition.length() - 1); + + } + + } + + // extracts file name from URL + + return fileUrl.substring(fileUrl.lastIndexOf("/") + 1, + + fileUrl.length()); + + } + +} \ No newline at end of file diff --git a/group06/949319266/homework003/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group06/949319266/homework003/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..183c8934d8 --- /dev/null +++ b/group06/949319266/homework003/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,117 @@ +package com.coderising.download.impl; + +import java.io.IOException; + +import java.net.HttpURLConnection; + +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 fileURL, int startPos, int endPos) throws ConnectionException { + + try { + + System.out.println("try to open file url: " + fileURL); + + + + URL url = new URL(fileURL); + + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + + + + // 设定读取range + + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + System.out.println("Range: bytes=" + startPos + "-" + endPos); + + + + int responseCode = httpConn.getResponseCode(); + + + + System.out.println("server replied HTTP code: " + responseCode); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_PARTIAL) { + + System.out.println("return new ConnectionImpl"); + + return new ConnectionImpl(httpConn, fileURL); + + } else { + + throw new ConnectionException("server replied HTTP code: " + responseCode); + + } + + } catch (IOException e) { + + throw new ConnectionException(e); + + } + + } + + + + @Override + + public int getContentLength(String fileURL) throws ConnectionException { + + try { + + System.out.println("try to open file url: " + fileURL); + + + + URL url = new URL(fileURL); + + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + + int responseCode = httpConn.getResponseCode(); + + + + System.out.println("server replied HTTP code: " + responseCode); + + if (responseCode == HttpURLConnection.HTTP_OK) { + + System.out.println("return contentLength: " + httpConn.getContentLength()); + + int contentLength = httpConn.getContentLength(); + + httpConn.disconnect(); + + return contentLength; + + } else { + + throw new ConnectionException("server replied HTTP code: " + responseCode); + + } + + } catch (IOException e) { + + throw new ConnectionException(e); + + } + + } + +} \ No newline at end of file diff --git a/group06/949319266/homework03/src/src/com/coderising/litestruts/Configuration.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/Configuration.java new file mode 100644 index 0000000000..1cd66a2f98 --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/Configuration.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +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/group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationException.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..c3e27f8a05 --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +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/group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationTest.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..59483720cd --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.coderising.litestruts; + +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/group06/949319266/homework03/src/src/com/coderising/litestruts/LoginAction.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..1005f35a29 --- /dev/null +++ b/group06/949319266/homework03/src/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/group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtil.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..9f6895c4f3 --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.coderising.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; + +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/group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtilTest.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..73f99988c7 --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +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/group06/949319266/homework03/src/src/com/coderising/litestruts/Struts.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..d6e91ad9df --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,171 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + + + +public class Struts { + + + + /** + + * 0. 读取配置文件struts.xml + + * + + * 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + + * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + + * ("name"="test" , "password"="1234") , + + * 那就应该调用 setName和setPassword方法 + + * + + * 2. 通过反射调用对象的execute 方法, 并获得返回值,例如"success" + + * + + * 3. 通过反射找到对象的所有getter方法(例如 getMessage), + + * 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + + * 放到View对象的parameters + + * + + * 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + + * 放到View对象的jsp字段中。 + + */ + + public static View runAction(String actionName, Map parameters) { + + Map actionMap = StrutsParser.doParse(); + + StrutsAction action = actionMap.get(actionName); + + + + if (action == null) { + + System.out.println("couldn't get action: " + actionName + ", return"); + + return null; + + } + + + + try { + + // 通过反射, 创建实例对象 + + Class actionClass = Class.forName(action.getActionClassName()); + + Object actionObj = actionClass.newInstance(); + + + + // 调用 parameters 中的 set 方法 + + for (Map.Entry parameterEntry : parameters.entrySet()) { + + Method[] methods = actionClass.getMethods(); + + for (Method method : methods) { + + if (method.getName().equalsIgnoreCase("set" + parameterEntry.getKey())) { + + method.invoke(actionObj, parameterEntry.getValue()); + + } + + } + + } + + + + // 调用 execute 方法 + + Method executeMethod = actionClass.getMethod("execute"); + + Object executeResult = executeMethod.invoke(actionObj); + + + + // 根据 execute 方法的结果, 获取 xml 配置的 jsp 页面 + + String jsp = action.getAttributes().get(Objects.toString(executeResult)); + + + + // 调用 get 方法 + + Map actionFieldMap = new HashMap<>(); + + Field[] actionFields = actionClass.getDeclaredFields(); + + for (Field actionFiled : actionFields) { + + Method[] methods = actionClass.getMethods(); + + for (Method method : methods) { + + if (method.getName().equalsIgnoreCase("get" + actionFiled.getName())) { + + method.invoke(actionObj); + + actionFieldMap.put(actionFiled.getName(), Objects.toString(method.invoke(actionObj))); + + } + + } + + } + + + + View view = new View(); + + view.setParameters(actionFieldMap); + + view.setJsp(jsp); + + return view; + + } catch (ClassNotFoundException e) { + + e.printStackTrace(); + + } catch (InstantiationException e) { + + e.printStackTrace(); + + } catch (IllegalAccessException e) { + + e.printStackTrace(); + + } catch (InvocationTargetException e) { + + e.printStackTrace(); + + } catch (NoSuchMethodException e) { + + e.printStackTrace(); + + } + + return null; + + } + +} diff --git a/group06/949319266/homework03/src/src/com/coderising/litestruts/StrutsTest.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..a44c1878ac --- /dev/null +++ b/group06/949319266/homework03/src/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/group06/949319266/homework03/src/src/com/coderising/litestruts/View.java b/group06/949319266/homework03/src/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..0194c681f6 --- /dev/null +++ b/group06/949319266/homework03/src/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group06/949319266/homework03/\345\233\233\346\254\241\346\226\207\347\253\240\345\234\260\345\235\200\346\261\207\346\200\273" "b/group06/949319266/homework03/\345\233\233\346\254\241\346\226\207\347\253\240\345\234\260\345\235\200\346\261\207\346\200\273" new file mode 100644 index 0000000000..a13cc729cf --- /dev/null +++ "b/group06/949319266/homework03/\345\233\233\346\254\241\346\226\207\347\253\240\345\234\260\345\235\200\346\261\207\346\200\273" @@ -0,0 +1 @@ +http://blog.sina.com.cn/s/articlelist_3255506984_0_1.html \ No newline at end of file diff --git a/group06/949319266/homework04/src/ClassFileLoader/ClassFileLoader.java b/group06/949319266/homework04/src/ClassFileLoader/ClassFileLoader.java new file mode 100644 index 0000000000..da0d90a7e5 --- /dev/null +++ b/group06/949319266/homework04/src/ClassFileLoader/ClassFileLoader.java @@ -0,0 +1,88 @@ +package ClassFileLoader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + private static final int BUFFER_SIZE = 1024; + public byte[] readBinaryCode(String className) { + byte[] result = null; + for(String path : clzPaths){ + File file = new File(getPath(path, className)); + if(!file.exists()){ + continue; + } + result = readFile(file); + } + return result; + } + /** + * ļݴֽз + */ + private byte[] readFile(File file){ + FileInputStream fileInputStream; + byte[] buffer = new byte[BUFFER_SIZE]; + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + try { + fileInputStream = new FileInputStream(file); + while(byteArrayOutputStream.size() < file.length()){ + int len = fileInputStream.read(buffer); + if(len < 0){ + break; + } + byteArrayOutputStream.write(buffer, 0, len); + } + } catch (Exception e) { + e.printStackTrace(); + } + if(byteArrayOutputStream.size() > file.length()){ + byte[] result = byteArrayOutputStream.toByteArray(); + return Arrays.copyOf(result, (int)file.length()); + } + return byteArrayOutputStream.toByteArray(); + } + /** + * ȡʵ·· + */ + private String getPath(String path ,String className){ + System.out.println(className); + String [] ways = className.split("\\."); + for (String string : ways) { + System.out.println(string); + } + StringBuilder builder = new StringBuilder(); + builder.append(path); + for (String string : ways) { + builder.append("\\"); + builder.append(string); + } + builder.append(".class"); + System.out.println(builder.toString()); + return builder.toString(); + } + private byte[] loadClassFile(String clzFileName) { + return null; + } + public void addClassPath(String path) { + clzPaths.add(path); +} + public String getClassPath_V1(){ + return null; + } + + public String getClassPath(){ + StringBuilder builder = new StringBuilder(); + for(int i = 0; i < clzPaths.size(); i++){ + builder.append(clzPaths.get(i)); + if(i < clzPaths.size() - 1){ + builder.append(";"); + } + } + return builder.toString(); + } +} diff --git a/group06/949319266/homework04/src/ClassFileLoader/ClassFileloaderTest.java b/group06/949319266/homework04/src/ClassFileLoader/ClassFileloaderTest.java new file mode 100644 index 0000000000..a4fb150fa1 --- /dev/null +++ b/group06/949319266/homework04/src/ClassFileLoader/ClassFileloaderTest.java @@ -0,0 +1,5 @@ +package ClassFileLoader; + +public class ClassFileloaderTest { + +} diff --git a/group06/949319266/homework04/src/ClassFileLoader/EmployeeV1.java b/group06/949319266/homework04/src/ClassFileLoader/EmployeeV1.java new file mode 100644 index 0000000000..e3104ecd79 --- /dev/null +++ b/group06/949319266/homework04/src/ClassFileLoader/EmployeeV1.java @@ -0,0 +1,23 @@ +package ClassFileLoader; + +public class EmployeeV1 { + private String name; + private int age; + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + } +} \ No newline at end of file diff --git a/group06/949319266/homework04/src/ClassFileLoader/LRUPageFrame.java b/group06/949319266/homework04/src/ClassFileLoader/LRUPageFrame.java new file mode 100644 index 0000000000..97ea2e966f --- /dev/null +++ b/group06/949319266/homework04/src/ClassFileLoader/LRUPageFrame.java @@ -0,0 +1,110 @@ +package ClassFileLoader; + +public class LRUPageFrame { + + private static class Node { + Node prev; + Node next; + int pageNum; + Node() { + } + Node(int pageNum){ + this.pageNum = pageNum; + } + } + private int capacity; + private Node first;// ͷ + private Node last;// β + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + /** + * ȡж + */ + public void access(int pageNum) { + if(first == null){ //һ + first = new Node(pageNum); + first.next = first.prev = null; + last = first; + }else if(size() < capacity && first != null){ //ҳδʱ + Node node = new Node(pageNum); + if(last.prev == null){ + last.prev = node; + node.next = last; + }else{ + node.next = first; + first.prev = node; + node.prev = null; + } + first = node; + }else if(size() >= capacity){ //ҳ + Node node = getNode(pageNum); + LRU(node, pageNum); + } + } + /** + * lru㷨 + */ + private void LRU(Node node, int pageNum){ + if(node != null){ + if(last.pageNum == node.pageNum){ //last + last = node.prev; + last.next = null; + node.next = first; + first.prev = node; + node.prev = null; + first = node; + }else if(last.pageNum != node.pageNum && first.pageNum != node.pageNum){ + //firstlastм䷶Χ + node.prev.next = node.next; + node.next.prev = node.prev; + node.prev = null; + node.next = first; + first = node; + } + }else{ + //» + last = last.prev; + last.next = null; + node = new Node(pageNum); + node.next = first; + first.prev = node; + first = node; + } + } + /** + * ڻлȡڵ + */ + private Node getNode(int pageNum){ + Node node = first; + while(node != null){ + if(node.pageNum == pageNum){ + return node; + } + node = node.next; + } + return null; + } + public int size(){ + int num = 0; + Node node = first; + while(node != null){ + num++; + node = node.next; + } + return num; + } + 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/group06/949319266/homework04/src/Test/ClassFileloaderTest.java b/group06/949319266/homework04/src/Test/ClassFileloaderTest.java new file mode 100644 index 0000000000..12e49611ff --- /dev/null +++ b/group06/949319266/homework04/src/Test/ClassFileloaderTest.java @@ -0,0 +1,65 @@ +package Test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import ClassFileLoader.ClassFileLoader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + static String path1 = "C:\\Users\\yanght\\Documents\\mygit\\coding2017-1\\group06\\1454385822\\bin"; + static String path2 = "D:\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.coding.basic.homework_04.jvm.test.EmployeeV1"; +// String className = "EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + // ע⣺ֽܺJVM汾йϵ Կõൽж + Assert.assertEquals(1084, byteCodes.length); + } + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coding.basic.homework_04.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 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/group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationException.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..97e286827f --- /dev/null +++ b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +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/group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationTest.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..734649f37a --- /dev/null +++ b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.coderising.litestruts; + +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/group06/949319266/lite-struts2/src/com/coderising/litestruts/LoginAction.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group06/949319266/lite-struts2/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/group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtil.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..0bd53fea93 --- /dev/null +++ b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.coderising.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; + +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/group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtilTest.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..cbe732d83f --- /dev/null +++ b/group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +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/group06/949319266/lite-struts2/src/com/coderising/litestruts/Struts.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..3e9678cbd8 --- /dev/null +++ b/group06/949319266/lite-struts2/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,171 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + + + +public class Struts { + + + + /** + + * 0. 读取配置文件struts.xml + + * + + * 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + + * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + + * ("name"="test" , "password"="1234") , + + * 那就应该调用 setName和setPassword方法 + + * + + * 2. 通过反射调用对象的execute 方法, 并获得返回值,例如"success" + + * + + * 3. 通过反射找到对象的所有getter方法(例如 getMessage), + + * 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + + * 放到View对象的parameters + + * + + * 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + + * 放到View对象的jsp字段中。 + + */ + + public static View runAction(String actionName, Map parameters) { + + Map actionMap = StrutsParser.doParse(); + + StrutsAction action = actionMap.get(actionName); + + + + if (action == null) { + + System.out.println("couldn't get action: " + actionName + ", return"); + + return null; + + } + + + + try { + + // 通过反射, 创建实例对象 + + Class actionClass = Class.forName(action.getActionClassName()); + + Object actionObj = actionClass.newInstance(); + + + + // 调用 parameters 中的 set 方法 + + for (Map.Entry parameterEntry : parameters.entrySet()) { + + Method[] methods = actionClass.getMethods(); + + for (Method method : methods) { + + if (method.getName().equalsIgnoreCase("set" + parameterEntry.getKey())) { + + method.invoke(actionObj, parameterEntry.getValue()); + + } + + } + + } + + + + // 调用 execute 方法 + + Method executeMethod = actionClass.getMethod("execute"); + + Object executeResult = executeMethod.invoke(actionObj); + + + + // 根据 execute 方法的结果, 获取 xml 配置的 jsp 页面 + + String jsp = action.getAttributes().get(Objects.toString(executeResult)); + + + + // 调用 get 方法 + + Map actionFieldMap = new HashMap<>(); + + Field[] actionFields = actionClass.getDeclaredFields(); + + for (Field actionFiled : actionFields) { + + Method[] methods = actionClass.getMethods(); + + for (Method method : methods) { + + if (method.getName().equalsIgnoreCase("get" + actionFiled.getName())) { + + method.invoke(actionObj); + + actionFieldMap.put(actionFiled.getName(), Objects.toString(method.invoke(actionObj))); + + } + + } + + } + + + + View view = new View(); + + view.setParameters(actionFieldMap); + + view.setJsp(jsp); + + return view; + + } catch (ClassNotFoundException e) { + + e.printStackTrace(); + + } catch (InstantiationException e) { + + e.printStackTrace(); + + } catch (IllegalAccessException e) { + + e.printStackTrace(); + + } catch (InvocationTargetException e) { + + e.printStackTrace(); + + } catch (NoSuchMethodException e) { + + e.printStackTrace(); + + } + + return null; + + } + +} diff --git a/group06/949319266/lite-struts2/src/com/coderising/litestruts/StrutsTest.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group06/949319266/lite-struts2/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/group06/949319266/lite-struts2/src/com/coderising/litestruts/View.java b/group06/949319266/lite-struts2/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group06/949319266/lite-struts2/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group08/1144989424/secondPractice/readme.md b/group08/1144989424/secondPractice/readme.md new file mode 100644 index 0000000000..f5644a6ce2 --- /dev/null +++ b/group08/1144989424/secondPractice/readme.md @@ -0,0 +1,3 @@ +### 第二次作业 +1. 完成数组练习题 +2. 读取xml文件,在利用反射生成类对象,反射获取get和set方法 \ No newline at end of file diff --git a/group08/1144989424/thirdPractice/readme.md b/group08/1144989424/thirdPractice/readme.md new file mode 100644 index 0000000000..d72cafdb2e --- /dev/null +++ b/group08/1144989424/thirdPractice/readme.md @@ -0,0 +1,9 @@ +### 第三次作业 +1. 完成链表练习题 +2. 实现多线程下载文件 + +博客更新 + +[数据库查询连接(JOIN)用法](http://blog.csdn.net/qq1332479771/article/details/62104624) + +[log4j日志级别](http://blog.csdn.net/qq1332479771/article/details/61927227) diff --git a/group08/1144989424/thirdPractice/src/download/DownloadThread.java b/group08/1144989424/thirdPractice/src/download/DownloadThread.java new file mode 100644 index 0000000000..5b3de789c6 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/DownloadThread.java @@ -0,0 +1,26 @@ +package download; + +import java.io.FileOutputStream; + +import download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + byte [] buff; + FileOutputStream file; + + public DownloadThread( Connection conn, int startPos, int endPos, byte[] buff ,FileOutputStream file){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.file = file; + this.buff = buff; + } + public void run(){ + + } +} diff --git a/group08/1144989424/thirdPractice/src/download/FileDownloader.java b/group08/1144989424/thirdPractice/src/download/FileDownloader.java new file mode 100644 index 0000000000..670ce43188 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/FileDownloader.java @@ -0,0 +1,73 @@ +package download; + +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; +import 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/group01/895457260/code/src/download/FileDownloaderTest.java b/group08/1144989424/thirdPractice/src/download/FileDownloaderTest.java similarity index 69% rename from group01/895457260/code/src/download/FileDownloaderTest.java rename to group08/1144989424/thirdPractice/src/download/FileDownloaderTest.java index 0792e6c0ba..c978cc43d2 100644 --- a/group01/895457260/code/src/download/FileDownloaderTest.java +++ b/group08/1144989424/thirdPractice/src/download/FileDownloaderTest.java @@ -1,8 +1,6 @@ package download; -import download.FileDownloader; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -10,11 +8,6 @@ import download.api.DownloadListener; import download.impl.ConnectionManagerImpl; -import java.io.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class FileDownloaderTest { boolean downloadFinished = false; @Before @@ -28,11 +21,8 @@ public void tearDown() throws Exception { @Test public void testDownload() { -// String url = "http://localhost:8080/test.jpg"; -// String url = "file:///E:/Video/download/88993.mp4"; -// String url = "file:///E:/Pictures/Clannad/Clannad高清图片/38.jpg"; - String url = "http://pic6.huitu.com/res/20130116/84481_20130116142820494200_1.jpg"; - + String url = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"; + FileDownloader downloader = new FileDownloader(url); @@ -56,7 +46,7 @@ public void notifyFinished() { System.out.println("还没有下载完成,休眠五秒"); //休眠5秒 Thread.sleep(5000); - } catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } } @@ -65,4 +55,5 @@ public void notifyFinished() { } + } diff --git a/group08/1144989424/thirdPractice/src/download/api/Connection.java b/group08/1144989424/thirdPractice/src/download/api/Connection.java new file mode 100644 index 0000000000..1a467a8086 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/api/Connection.java @@ -0,0 +1,23 @@ +package 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/group08/1144989424/thirdPractice/src/download/api/ConnectionException.java b/group08/1144989424/thirdPractice/src/download/api/ConnectionException.java new file mode 100644 index 0000000000..13cf1a4729 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group08/1144989424/thirdPractice/src/download/api/ConnectionManager.java b/group08/1144989424/thirdPractice/src/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1519ebb787 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group08/1144989424/thirdPractice/src/download/api/DownloadListener.java b/group08/1144989424/thirdPractice/src/download/api/DownloadListener.java new file mode 100644 index 0000000000..4119e46144 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group08/1144989424/thirdPractice/src/download/impl/ConnectionImpl.java b/group08/1144989424/thirdPractice/src/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..24180cc013 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/impl/ConnectionImpl.java @@ -0,0 +1,39 @@ +package download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLConnection; + +import download.api.Connection; + +public class ConnectionImpl implements Connection{ + + URLConnection urlConn; + + public URLConnection getUrlConn() { + return urlConn; + } + + public void setUrlConn(URLConnection urlConn) { + this.urlConn = urlConn; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + InputStream input = urlConn.getInputStream(); + byte[] bytes = new byte[endPos-startPos]; + input.read(bytes, startPos, endPos); + return bytes; + } + + @Override + public int getContentLength() { + return urlConn.getContentLength(); + } + + @Override + public void close() { + urlConn = null; + } + +} diff --git a/group08/1144989424/thirdPractice/src/download/impl/ConnectionManagerImpl.java b/group08/1144989424/thirdPractice/src/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..6b28bf9b29 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,41 @@ +package download.impl; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import download.api.Connection; +import download.api.ConnectionException; +import download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + URL uu = null; + ConnectionImpl conn = null; + try { + uu = new URL(url); + URLConnection urlConn = uu.openConnection(); + conn.setUrlConn(urlConn); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + + + return conn; + } + + public static void main(String [] args){ + ConnectionManagerImpl cmi = new ConnectionManagerImpl(); + try { + cmi.open("https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"); + } catch (ConnectionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/group08/1144989424/thirdPractice/src/download/impl/DownloadListenerImpl.java b/group08/1144989424/thirdPractice/src/download/impl/DownloadListenerImpl.java new file mode 100644 index 0000000000..a18e1262b6 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/download/impl/DownloadListenerImpl.java @@ -0,0 +1,11 @@ +package download.impl; + +import download.api.DownloadListener; + +public class DownloadListenerImpl implements DownloadListener{ + + @Override + public void notifyFinished(){ + + } +} diff --git a/group08/1144989424/thirdPractice/src/linkedlist/MyIterator.java b/group08/1144989424/thirdPractice/src/linkedlist/MyIterator.java new file mode 100644 index 0000000000..fb71445850 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/linkedlist/MyIterator.java @@ -0,0 +1,7 @@ +package linkedlist; + +public interface MyIterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group08/1144989424/thirdPractice/src/linkedlist/MyLinkedList.java b/group08/1144989424/thirdPractice/src/linkedlist/MyLinkedList.java new file mode 100644 index 0000000000..31d45f02c5 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/linkedlist/MyLinkedList.java @@ -0,0 +1,328 @@ +package linkedlist; + +import java.util.Comparator; + +/** + * 实现LinkedList基本功能 + * @author Wayss + * 2017-02-23 + */ + +public class MyLinkedList implements MyList { + + private Node head; + private int size = 0; + + public void add(Object o){ + Node n = new Node(o); + head.next = n; + size++; + } + public void add(int index , Object o){ + //1.index校验 + if(index < 0 || index > size){ + throw new IndexOutOfBoundsException("插入的下标越界了:"+"插入的下标为:"+index+"集合大小为:"+size); + } + //2. 查找index位置的前一个节点 + //tempNode为当前链表的第一个节点 + Node tempNode = head.next; + for(int i = 0; i < index - 1 ; i++){ + tempNode = tempNode.next; + } + Node behindNode = tempNode.next; + Node insertNode = new Node(o); + tempNode.next = insertNode; + insertNode.next = behindNode; + size++; + } + public Object get(int index){ + //1.index校验 + if(index < 0 || index > size){ + throw new IndexOutOfBoundsException("插入的下标越界了:"+"插入的下标为:"+index+"集合大小为:"+size); + } + //2. 查找当前节点 + Node tempNode = head.next; + for(int i = 0; i < index; i++){ + tempNode = tempNode.next; + } + return tempNode.data; + } + public Object remove(int index){ + //1.index校验 + if(index < 0 || index > size){ + throw new IndexOutOfBoundsException("插入的下标越界了:"+"插入的下标为:"+index+"集合大小为:"+size); + } + //2. 查找当前节点的上一个节点 + Node tempNode = head.next; + for(int i = 0; i < index - 1; i++){ + tempNode = tempNode.next; + } + Node deleteNode = tempNode.next; + Node behideNode = tempNode.next.next; + tempNode.next = behideNode; + size--; + return deleteNode.data; + } + + public int size(){ + return size; + } + + public void addFirst(Object o){ + Node insertNode = new Node(o); + insertNode.next = head.next; + head.next = insertNode; + size++; + } + public void addLast(Object o){ + Node insertNode = new Node(o); + Node tempNode = head.next; + for(int i = 0; i < size; i++){ + tempNode = tempNode.next; + } + tempNode.next = insertNode; + size++; + } + public Object removeFirst(){ + Node firstNode = head.next; + head = firstNode.next; + size--; + return firstNode; + } + public Object removeLast(){ + Node tempNode = head.next; + //1.移除需要找到最后一个点的前一个点 + for(int i = 0; i < size - 1; i++){ + tempNode = tempNode.next; + } + Node deleteNode = tempNode.next; + tempNode.next = null; + size--; + return deleteNode; + } + + public MyIterator iterator(){ + return new MyLinkedListIterator(this); + } + + private class MyLinkedListIterator implements MyIterator{ + private MyLinkedList list = null; + private int index = 0; + + private MyLinkedListIterator(MyLinkedList list){ + this.list = list; + } + + @Override + public boolean hasNext(){ + if(index < size){ + return true; + } + return false; + } + + @Override + public Object next(){ + return list.get(index++); + } + } + + private static class Node{ + Object data; + Node next; + public Node(Object data){ + this.data = data; + } + } + public void set(int i, Object obj){ + remove(i); + add(i,obj); + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + //单链表的实现方法,遍历了一遍 + //如果是双向链表的话,逆置就简单多了 + int half = size/2; + for(int i = 0; i < half; i ++){ + Object o1 = get(i); + set(i,o1); + Object o2 = get(size - 1 - i); + set(size - 1 - i, o2); + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + int half = size/2; + Node tempNode = head.next; + for(int i = 0; i < half; i++){ + tempNode = tempNode.next; + } + //通过移动head指针来实现移除前半部分 + head.next = tempNode; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i < 0 || i > size || i < length || length < 0 || length > size){ + return; + } + + Node tempNode = head.next; + for(int j = 0; j < i; j++){ + tempNode = tempNode.next; + } + Node n1 = tempNode; + + for(int j = i; j < length; j++){ + tempNode = tempNode.next; + } + Node n2 = tempNode; + + //移除n1到n2中间的元素 + n1.next = n2; + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(MyLinkedList list){ + if(list == null){ + return null; + } + + Node tempNode = head.next; + Node result = head; + int[] res = new int[list.size()]; + + for(int j = 0,i = 0; j < size; j++){ + if(j == (int)list.removeFirst()){ + result.next = tempNode; + res[i++] = (int) tempNode.data; + }else{ + tempNode = tempNode.next; + } + } + +// return result; + return res; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + * @param list + */ + + public void subtract(MyLinkedList list){ + + //方法一 + //1.对list递增排序 + //2.遍历当前链表,同时和list做比较,向后移动list指针,注意是递增的 + + //方法二 + //1.两层遍历嵌套 + for(int i = 0; i < list.size(); i++){ + for(int j = 0; j < size; j++){ + if(list.get(i).equals(this.get(j))){ + this.remove(j); + } + } + } + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + //1.遍历链表,比较后一个和当前的大小, + //2.相等则,删除后一个,同时再比较原先删除的节点的后一个(可能需要while) + for(int i = 0; i < size; i++){ + while(this.get(i).equals(this.get(i+1))){ + this.remove(i+1); + //由于remove会把size的大小减一,所以,不会出现数组越界 + i++; + //i++的目的是为了判断连续多个值相等的情况 + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + //1.找到第一个值大于min的节点,的前一个节点 + //2.找到第一个值小于max的节点 + //3.用第一步找出的节点指向第二步找出的节点的next + Node minNode = head.next; + Node maxNode = head.next; + + int first = 0; + int last = 0; + //循环停止的条件是,找到了第一个节点不小于min的点了。 + //所以,minNode也就没有再往后移动了。即,在不小于min的第一个点的前一个 + while((int)this.get(first++) < min){ + minNode = minNode.next; + } + + while((int)this.get(last++) < max){ + maxNode = maxNode.next; + } + //maxNode往后再移动一个位置,表示的是第一个不小于max的点 + maxNode = maxNode.next; + + minNode.next = maxNode; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public MyLinkedList intersection( MyLinkedList list){ + //1.假设当前链表节点个数是m,list中的节点个数是n + //2.现在需要遍历m+n次,依次把值给链表C传递,同时,给C链表add的时候,注意比较大小 + MyLinkedList result = new MyLinkedList(); + int i = 0; + int j = 0; + while(i < size){ + while(j < list.size()){ + if((int)this.get(i) < (int)list.get(j)){ + result.add(this.get(i)); + i++; + }else if((int)this.get(i) == (int)list.get(j)){ + result.add(this.get(i)); + i++; + j++; + }else{ + result.add(list.get(j)); + j++; + } + } + } + + return result; + } + +} diff --git a/group08/1144989424/thirdPractice/src/linkedlist/MyList.java b/group08/1144989424/thirdPractice/src/linkedlist/MyList.java new file mode 100644 index 0000000000..f5cd0f5731 --- /dev/null +++ b/group08/1144989424/thirdPractice/src/linkedlist/MyList.java @@ -0,0 +1,9 @@ +package linkedlist; + +public interface MyList { + 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/group08/1425809544/03-05/com/array/ArrayUtil.java b/group08/1425809544/03-05/com/array/ArrayUtil.java new file mode 100644 index 0000000000..f370e38dd4 --- /dev/null +++ b/group08/1425809544/03-05/com/array/ArrayUtil.java @@ -0,0 +1,257 @@ +package com.util_1; + +import java.util.*; + +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 = origin; + int newLength = oldArr.length; + int[] newArr = new int[newLength]; + for (int i = 0; i < newLength; i++) { + newArr[newLength - i - 1] = oldArr[i]; + } + for (int s : newArr) { + System.out.println(s); + } + + + } + + /** + * 现在有如下的一个数组: 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) { + int[] oldArr = oldArray; + int oldLength = oldArr.length; + int[] newArr = new int[oldLength]; + int index = 0; + int zeroCount = 0; + for (int i = 0; i < oldLength; i++) { + if (oldArr[i] == 0) { + zeroCount++; + } else { + newArr[index++] = oldArr[i]; + } + } + int[] newArrs = Arrays.copyOf(newArr, index); + return newArrs; + } + + /** + * 给定两个已经排序好的整形数组, 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) { + int newLength = array1.length + array2.length; + int[] newArr = new int[newLength]; + int index = 0; + for (int i = 0; i < array1.length; i++) { + newArr[index++] = array1[i]; + } + for (int i = 0; i < array2.length; i++) { + newArr[index++] = array2[i]; + } + //冒泡排序 + for (int i = 0; i < newArr.length; i++) { + for (int j = i + 1; j < newArr.length; j++) { + if (newArr[i] > newArr[j]) { + int temp = newArr[i]; + newArr[i] = newArr[j]; + newArr[j] = temp; + } + } + } + //数组去重 + boolean[] b = new boolean[newArr.length]; + int counts = newArr.length; + for (int i = 0; i < newArr.length; i++) { + for (int j = i + 1; j < newArr.length; j++) { + if (newArr[i] == newArr[j] && b[i] == false) { + b[j] = true; + counts--; + } + } + } + int[] result = new int[counts]; + int j = 0; + for (int i = 0; i < newArr.length; i++) { + if (b[i] == false) { + result[j] = newArr[i]; + j++; + } + } + 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) { + int oldLength = oldArray.length; + int newLength = oldLength + size; + int[] result = Arrays.copyOf(oldArray, newLength); + return result; + } + + /** + * 斐波那契数列为: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) { + int a = 1, b = 1, c = 2; + int[] arr = new int[max + 1]; + int i = 2; + if (max == 1) { + return Arrays.copyOf(arr, 0); + } else if (max <= 0) { + throw new IllegalArgumentException("不能输入<=0的参数:" + max); + } else { + arr[0] = 1; + arr[1] = 1; + do { + c = a + b; + a = b; + b = c; + arr[i++] = c; + } while (c < max); + } + + if (arr[i - 1] >= max) { + return Arrays.copyOf(arr, i - 1); + } + return Arrays.copyOf(arr, i); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * + * @param max + * @return + */ + public int[] getPrimes(int max) { + + class IsPrime { + // 判断某整数是否为素数 + public boolean isPrimes(int n) { + if (n < 2) { + return false; + } + for (int i = 2; i * i <= n; i++) { + if (n % i == 0) { + return false; + } + } + return true; + + } + } + List list = new ArrayList(); + IsPrime isPrime = new IsPrime(); + for (int i = 2; i < max; i++) { + if (isPrime.isPrimes(i)) { + list.add(i); + } + } + + int[] arr = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + arr[i] = (int) list.get(i); + } + + return arr; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * + * @param max + * @return + */ + public int[] getPerfectNumbers(int max) { + //保存每组的分解因子 + List list = new ArrayList(); + List pm = new ArrayList(); + int sum = 0; + //除数 + for (int i = 2; i < max; i++) { + //被除数 + sum=0; + for (int j = 1; j < i / 2 + 1; j++) { + if (i % j == 0) { + list.add(j); + sum += j; + } + } + + if (sum == i) { + pm.add(i); + } + + list.clear(); + } + + int[] pmaArr = new int[pm.size()]; + for (int i = 0; i < pm.size(); i++) { + pmaArr[i] = (int) pm.get(i); + } + return pmaArr; + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * + * @param array + * @param + * @return + */ + + public String join(int[] array, String seperator) { + + String s = new String(); + for (int i = 0; i < array.length; i++) { + if (i < array.length - 1) { + s += array[i] + seperator; + } else { + s += array[i]; + } + } + return s; + } + + +} diff --git a/group08/1425809544/03-05/com/array/ArrayUtilTest.java b/group08/1425809544/03-05/com/array/ArrayUtilTest.java new file mode 100644 index 0000000000..ad348045f9 --- /dev/null +++ b/group08/1425809544/03-05/com/array/ArrayUtilTest.java @@ -0,0 +1,99 @@ +package com.util_1; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by 14258 on 2017/2/28. + */ +public class ArrayUtilTest { + ArrayUtil arrayUtil = new ArrayUtil(); + + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void testReverseArray() throws Exception { + + int[] testArr = {7, 9, 30, 3}; + + arrayUtil.reverseArray(testArr); + } + + @Test + public void testRemoveZero() throws Exception { + int oldArr[] = {1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 0, 5}; + int[] newArr = arrayUtil.removeZero(oldArr); + for (int s : newArr) { + System.out.println(s); + } + + } + + @Test + public void testMerge() throws Exception { + int[] a1 = {3, 5, 7}; + int[] a2 = {4, 5, 6, 7}; + int[] newArr = arrayUtil.merge(a1, a2); + for (int s : newArr) { + System.out.println(s); + } + } + + @Test + public void testGrow() throws Exception { + int[] oldArray = {2, 3, 6}; + + int[] newArr = arrayUtil.grow(oldArray, 3); + + for (int s : newArr) { + System.out.println(s); + } + } + + @Test + public void testFibonacci() throws Exception { + + int[] newArr = arrayUtil.fibonacci(16); + System.out.print("["); + for (int i : newArr) { + System.out.print(i+","); + } + System.out.print("]"); + } + + @Test + public void testGetPrimes() throws Exception { + int[] prime = arrayUtil.getPrimes(23); + + for (int i :prime){ + System.out.print(i+" "); + } + } + + @Test + public void testGetPerfectNumbers() throws Exception { + int[] prime = arrayUtil.getPerfectNumbers(10000); + + for (int i :prime){ + System.out.print(i+" "); + } + } + + @Test + public void testJoin() throws Exception { + int[] array = {3, 8, 9}; + String s = arrayUtil.join(array, "-"); + System.out.println(s); + } +} \ No newline at end of file diff --git "a/group08/1425809544/03-05/\346\226\207\347\253\240\351\223\276\346\216\245-\350\256\241\347\256\227\346\234\272\345\255\230\345\202\250\345\231\250\347\273\223\346\236\204.txt" "b/group08/1425809544/03-05/\346\226\207\347\253\240\351\223\276\346\216\245-\350\256\241\347\256\227\346\234\272\345\255\230\345\202\250\345\231\250\347\273\223\346\236\204.txt" new file mode 100644 index 0000000000..ec8fa593de --- /dev/null +++ "b/group08/1425809544/03-05/\346\226\207\347\253\240\351\223\276\346\216\245-\350\256\241\347\256\227\346\234\272\345\255\230\345\202\250\345\231\250\347\273\223\346\236\204.txt" @@ -0,0 +1 @@ +[洢ṹ](http://note.youdao.com/noteshare?id=a2da59b294d277d0e828f4f566015014&sub=04848681007A4C4A8649A411729AEADC) \ No newline at end of file diff --git a/group08/1425809544/03-12/code/com/xyy/baselinked/Iterator.java b/group08/1425809544/03-12/code/com/xyy/baselinked/Iterator.java new file mode 100644 index 0000000000..72320aade3 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/baselinked/Iterator.java @@ -0,0 +1,12 @@ +package xyy.baselinked; + +/** + * Created by 14258 on 2017/3/14. + */ +public interface Iterator { + + public boolean hasNext(); + + public Object next(); + +} diff --git a/group08/1425809544/03-12/code/com/xyy/baselinked/LinkedList.java b/group08/1425809544/03-12/code/com/xyy/baselinked/LinkedList.java new file mode 100644 index 0000000000..096b73c311 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/baselinked/LinkedList.java @@ -0,0 +1,372 @@ +package xyy.baselinked; + +/** + * Created by 14258 on 2017/3/14. + */ +public class LinkedList implements List { + + private Node head; + private int size; + + + @Override + public void add(Object o) { + addLast(o); + } + + @Override + public void add(int index, Object o) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException(); + } + if (index == 0) { + addFirst(o); + return; + } + + if (index == size) { + addLast(o); + return; + } + + Node newNode = new Node(o); + Node node = head; + for (int i = 1; i < index; i++) { + node = node.next; + } + newNode.next = node.next; + node.next = newNode; + size++; + } + + @Override + public Object remove(int index) { + + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + + if (index == 0) { + return removeFirst(); + } + Node node = head; + Node pre = head; + for (int i = 1; i < index; i++) { + if (node.next != null) { + pre = node; + node = node.next; + } + } + + Object obj = node.data; + if (head.next == null) { + head = null; + pre = null; + } else if (node.next == null) { + pre.next = null; + node = null; + } else { + pre.next = node.next; + node.next = null; + node = null; + } + size--; + return obj; + } + + @Override + public int size() { + return size; + } + + @Override + public Object get(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + Node node = head; + for (int i = 0; i < index; i++) { + node = node.next; + } + Object data = node.data; + return data; + } + + + public void addFirst(Object o) { + Node newNode = new Node(o); + newNode.next = head; + head = newNode; + size++; + } + + public void addLast(Object o) { + Node newNode = new Node(o); + if (head == null) { + head = newNode; + } else { + if (head.next == null) { + head.next = newNode; + } else { + Node node = head; + for (int i = 1; i < size; i++) { + node = node.next; + } + node.next = newNode; + } + } + } + + public Object removeFirst() { + if (size <= 0) { + throw new IndexOutOfBoundsException(); + } + Node node = head; + head = node.next; + node.next = null; + size--; + return node.data; + + } + + public Object removeLast() { + if (size <= 0) { + throw new IndexOutOfBoundsException(); + } + Node node = head; + for (int i = 1; i < size; i++) { + node = node.next; + } + Object data = node.next.data; + node.next = null; + size--; + return data; + } + + + private class LinkedListIterator implements Iterator { + private Node node = head; + + public boolean hasNext() { + return node != null; + } + + public Object next() { + Object data = node.data; + node = node.next; + return data; + } + + public void moveFirst() { + node = head; + } + } + + public Iterator iterator() { + return new LinkedListIterator(); + } + + private static class Node { + Object data; + Node next; + + public Node(Object data) { + this.data = data; + } + } + + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { +// Node node = head.next; +// Object[] arr = new Object[size]; +// int i = size - 1; +// while (i >= 0) { +// arr[i--] = node.data; +// node = node.next; +// } +// node = head.next; +// for (int j = 0; j < size; j++) { +// node.data = arr[j]; +// node = node.next; +// } + if (size <= 0) { + throw new IndexOutOfBoundsException("链表下表越界" + size); + } + Node node = head; + Node minNode = node; + int length = size; + for (int i = 0; i < length; i++) { + if (node.next != null) { + node = node.next; + addFirst(node.data); + } + } + minNode.next = null; + node = null; + size = length; + + } + + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 + */ + + + public void removeFirstHalf() { + if (size <= 0) { + throw new IndexOutOfBoundsException("链表下标越界" + size); + } + Node node = head; + Node pre = head; + int count = 0; + for (int i = 0; i < size / 2; i++) { + pre = node; + node = node.next; + count++; + } + + head = node; + pre.next = null; + pre = null; + size = size - count; + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + + public void remove(int i, int length) { + + if (i < 0 || i >= size || length < 0 || length > size || (i + length > size)) { + throw new IndexOutOfBoundsException(); + } + + Node node = head; + Node pre = head; + Node iNode = head; + for (int j = 0; j < i + length; j++) { + if (node.next != null) { + pre = node; + if (j == (i - 1)) { + iNode = node; + } + node = node.next; + } + } + + if (i == 0) { + head = node; + } else { + iNode.next = node; + } + + pre.next = null; + pre = null; + size = size() - length; + + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = + * 11->101->201->301->401->501->601->701 listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + if (list == null || list.size() == 0) { + throw new IndexOutOfBoundsException(); + } + int[] arr = new int[list.size()]; + for (int i = 1; i < list.size(); i++) { + int index = (Integer) list.get(i); + arr[i] = (Integer) get(index); + } + return null; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + public void subtract(LinkedList list) { + if (list == null || list.size() == 0) { + return; + } + for (int i = 0; i < list.size(); i++) { + int data = (Integer) list.get(i); + LinkedListIterator iterator = (LinkedListIterator) this.iterator(); + int index = 0; + while (iterator.hasNext()) { + int obj = (Integer) iterator.next(); + if (obj == data) { + remove(index); + iterator.moveFirst(); + break; + } + index++; + } + } + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (head == null) { + return; + } + Node node = head; + Node pre = head; + while (node.next != null) { + node = node.next; + int value = (Integer) pre.data; + if ((Integer) node.data == value) { + //如果node 下一个是null.直接把node前一个pre的next指向空 + if (node.next == null) { + pre.next = null; + size--; + break; + } + pre.next = node.next; + node = node.next; + size--; + } + pre = pre.next; + } + } + + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + + + + + + + + + + + + + + +} + diff --git a/group08/1425809544/03-12/code/com/xyy/baselinked/List.java b/group08/1425809544/03-12/code/com/xyy/baselinked/List.java new file mode 100644 index 0000000000..39a0e1ba83 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/baselinked/List.java @@ -0,0 +1,17 @@ +package xyy.baselinked; + +/** + * Created by 14258 on 2017/3/14. + */ +public interface List { + + public void add(Object o); + + public void add(int index, Object o); + + public Object remove(int index); + + public int size(); + + public Object get(int index); +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/DownloadThread.java b/group08/1425809544/03-12/code/com/xyy/download/DownloadThread.java new file mode 100644 index 0000000000..f81c42098d --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/DownloadThread.java @@ -0,0 +1,67 @@ +package xyy.download; + +import xyy.download.api.Connection; + +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Created by 14258 on 2017/3/14. + */ +public class DownloadThread extends Thread { + + private int startPos; + private int endPos; + private boolean isDownloadEnd; + private String threadName; + private Connection connection; + private FileDownloader fileDownLoader; + + public DownloadThread(Connection connection, int startPos, int endPos, String threadName, FileDownloader fileDownloader) { + this.startPos = startPos; + this.endPos = endPos; + this.threadName = threadName; + this.connection = connection; + this.fileDownLoader = fileDownloader; + this.setName(threadName); + } + + + @Override + public void run(){ + try { + byte [] data = connection.read(startPos,endPos); + connection.close(); + System.out.println("下载线程名字"+threadName+"正在读取开始位置"+startPos+"结束位置"+endPos); + + int writelen=-1; + RandomAccessFile randomAccessFile = null; + randomAccessFile = new RandomAccessFile(fileDownLoader.fileName,"rw" ); + randomAccessFile.seek(startPos); + randomAccessFile.write(data,0,data.length); + writelen = data.length; + + isDownloadEnd = true; + fileDownLoader.addDownNumber(); + + + + + + + + + + + + } catch (IOException e) { + e.printStackTrace(); + } + + + } + + + + +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/FileDownloader.java b/group08/1425809544/03-12/code/com/xyy/download/FileDownloader.java new file mode 100644 index 0000000000..44ed7aba52 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/FileDownloader.java @@ -0,0 +1,116 @@ +package xyy.download; + +import vvv.download.api.ConnectionException; +import xyy.download.api.Connection; +import xyy.download.api.ConnectionManager; +import xyy.download.api.DownloadListener; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Created by 14258 on 2017/3/14. + */ +public class FileDownloader { + + private static final int threadNumber = 3;//下载线程数 + private String url;//传入的url地址 + public String fileName = "D://download"; + + private DownloadListener listener;//下载监听器; + private ConnectionManager connectionManager;//下载管理器; + //设置url + public FileDownloader(String url) { + this.url = url; + } + //设置下载链接管理 + public void setConnectionManager(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + //设置下载监听器 + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + //执行下载 + public void execute() { + + Connection conn = null; + try { + try { + conn = connectionManager.open(this.url);//又连接管理器打开根据url打开来连接 + } catch (ConnectionException e) { + e.printStackTrace(); + } + int length = conn.getContentLength();//获取conn长度 + this.fileName = fileName + "//" + conn.getFileName();//获取文件名字 + conn.close(); + startDownload(length, threadNumber); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + + + } + + private void startDownload(int length, int i) { + if (length <= 0) { + listener.notifyFinished(); + return; + } + + //设置一个和将要下载的文件一个同样大小的临时文件 + RandomAccessFile randomAccessFile = null; + try { + randomAccessFile = new RandomAccessFile(this.fileName, "rw"); + randomAccessFile.setLength(length); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + randomAccessFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + int block = length / threadNumber; + block = block == 0 ? block : block + 1; + System.out.println("length"+length+"block"+block); + for (i=0;i=threadNumber){ + if (listener!=null){ + listener.notifyFinished(); + } + } + + + + + } +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/FileDownloaderTest.java b/group08/1425809544/03-12/code/com/xyy/download/FileDownloaderTest.java new file mode 100644 index 0000000000..d0c533bd00 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/FileDownloaderTest.java @@ -0,0 +1,53 @@ +package xyy.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import xyy.download.api.ConnectionManager; +import xyy.download.api.DownloadListener; +import xyy.download.impl.ConnectionManagerImpl; + +/** + * Created by 14258 on 2017/3/14. + */ +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://img.71lady.com/uploads/allimg/1701/2-1F11GKT4.jpg"; + FileDownloader fileDownloader = new FileDownloader(url); + ConnectionManager connectionManager = new ConnectionManagerImpl(); + fileDownloader.setConnectionManager(connectionManager); + fileDownloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + }); + + fileDownloader.execute(); + + while (!downloadFinished) { + System.out.print("还没有下载完成,休眠五秒"); + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + } + +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/api/Connection.java b/group08/1425809544/03-12/code/com/xyy/download/api/Connection.java new file mode 100644 index 0000000000..de6a9f339f --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/api/Connection.java @@ -0,0 +1,32 @@ +package xyy.download.api; + +import java.io.IOException; + +/** + * Created by 14258 on 2017/3/14. + */ +public interface Connection { + + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos, int endPos) throws IOException; + + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + public String getFileName(); + + /** + * 关闭连接 + */ + public void close(); + + +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/api/ConnectionException.java b/group08/1425809544/03-12/code/com/xyy/download/api/ConnectionException.java new file mode 100644 index 0000000000..9877e4bf14 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/api/ConnectionException.java @@ -0,0 +1,11 @@ +package xyy.download.api; + +/** + * Created by 14258 on 2017/3/14. + */ +public interface ConnectionException { + + + + +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/api/ConnectionManager.java b/group08/1425809544/03-12/code/com/xyy/download/api/ConnectionManager.java new file mode 100644 index 0000000000..bd2c9fff44 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/api/ConnectionManager.java @@ -0,0 +1,25 @@ +package xyy.download.api; + +import vvv.download.api.ConnectionException; + +import java.io.IOException; + +/** + * Created by 14258 on 2017/3/14. + */ +public interface ConnectionManager { + + + /** + * 给定一个url , 打开一个连接 + * + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException, IOException; + + + + + +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/api/DownloadListener.java b/group08/1425809544/03-12/code/com/xyy/download/api/DownloadListener.java new file mode 100644 index 0000000000..ded3895179 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/api/DownloadListener.java @@ -0,0 +1,9 @@ +package xyy.download.api; + +/** + * Created by 14258 on 2017/3/14. + */ +public interface DownloadListener { + + public void notifyFinished(); +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionImpl.java b/group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..b40b123a1f --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionImpl.java @@ -0,0 +1,120 @@ +package xyy.download.impl; + +import xyy.download.api.Connection; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLDecoder; + +/** + * Created by 14258 on 2017/3/14. + */ +public class ConnectionImpl implements Connection { + + + private HttpURLConnection httpUrlConnection;//连接 + private String url;//url + private String contentType;//类型 + private String contentFileName;//文件名 + private int contentLength;//文件长度 + + + public ConnectionImpl(String url) throws IOException { + this.url = url; + httpUrlConnection = createConn(this.url); + if (httpUrlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { + this.contentLength = httpUrlConnection.getContentLength(); + this.contentType = httpUrlConnection.getContentType(); + this.contentFileName = getName(); + System.out.println("contentType" + httpUrlConnection.getContentType() + "fileName" + this.contentFileName + "contentType" + contentType); + } + } + + public ConnectionImpl(String url, boolean b) throws IOException { + close(); + this.url = url; + httpUrlConnection = createConn(this.url); + } + + private String getName() { + String fileName; + String disposition = httpUrlConnection.getHeaderField("Content-Disposition"); + if (disposition != null && !"".equals(disposition)) { + fileName = disposition.split(";")[1].split("=")[1].replaceAll("\"", ""); + } else { + fileName = url.substring(url.lastIndexOf("/") + 1); + } + + if (fileName != null && !"".equals(fileName)) { + try { + fileName = URLDecoder.decode(fileName, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } else { + fileName = "file_" + (int) (Math.random() * 10); + } + return fileName; + } + + + private HttpURLConnection createConn(String url) throws IOException { + HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); + conn.setConnectTimeout(5 * 1000); + conn.setReadTimeout(10 * 1000); + conn.setRequestMethod("GET"); + conn.setRequestProperty("User-Agent", "vvv download"); + conn.setRequestProperty("Connection", "Keep-Alive"); + conn.setRequestProperty("Keep-Alive", "300"); + return conn; + } + + + //读链接 + @Override + public byte[] read(int startPos, int endPos) throws IOException { + return new byte[0]; + } + + //获取链接长度 + @Override + public int getContentLength() { + return this.contentLength; + } + + //获取文件名字 + @Override + public String getFileName() { + return this.contentFileName; + } + + //关闭连接 + @Override + public void close() { + if (httpUrlConnection != null) { + httpUrlConnection.disconnect(); + httpUrlConnection = null; + } + } + + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getContentFileName() {return contentFileName;} + + public void setContentFileName(String contentFileName) { + this.contentFileName = contentFileName; + } + + public void setContentLength(int contentLength) { + this.contentLength = contentLength; + } +} diff --git a/group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionManagerImpl.java b/group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..05f9f401c6 --- /dev/null +++ b/group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,31 @@ +package xyy.download.impl; + + +import vvv.download.api.ConnectionException; +import xyy.download.api.Connection; +import xyy.download.api.ConnectionManager; + +import java.io.IOException; + +/** + * Created by 14258 on 2017/3/14. + */ +public class ConnectionManagerImpl implements ConnectionManager { + private String url; + + @Override + public Connection open(String url) throws ConnectionException, IOException { + + Connection conn = null; + if (!url.equals(this.url)){ + conn = new ConnectionImpl(url); + this.url = url; + }else { + conn = new ConnectionImpl(url, false); + } + + + + return conn; + } +} diff --git a/group08/1425809544/1425809544.md "b/group08/1425809544/1425809544-\345\215\232\345\256\242\345\234\260\345\235\200.md" similarity index 67% rename from group08/1425809544/1425809544.md rename to "group08/1425809544/1425809544-\345\215\232\345\256\242\345\234\260\345\235\200.md" index 326924a615..d314d00620 100644 --- a/group08/1425809544/1425809544.md +++ "b/group08/1425809544/1425809544-\345\215\232\345\256\242\345\234\260\345\235\200.md" @@ -1,3 +1,4 @@ ## 博客 - [文章链接-java集合 容器 简单概述](http://blog.csdn.net/qq_25385555/article/month/2017/02) - [文章链接-计算机存储器结构](http://blog.csdn.net/qq_25385555/article/month/2017/03) +-[文章链接-2017-3月- 工作-随想](http://blog.csdn.net/qq_25385555/article/details/62226463) diff --git a/group08/286060098/3-27/pom.xml b/group08/286060098/3-27/pom.xml new file mode 100644 index 0000000000..539f9eb4a9 --- /dev/null +++ b/group08/286060098/3-27/pom.xml @@ -0,0 +1,91 @@ + + + + 3-27 + 3-27 + 1.0.0- + + 4.0.0 + + + 4.1 + 3.5 + 19.0 + + 1.8 + 1.8 + + 1.7.5 + + true + 4.11 + 1.6.1 + 2.0.1 + + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + com.google.guava + guava + ${guava.version} + + + + junit + junit-dep + ${junit-dep.version} + + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${jdk.source.version} + ${jdk.target.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${maven-surefire-plugin.skip} + + + + + + + \ No newline at end of file diff --git a/group08/286060098/3-27/src/com/coderising/jvm/loader/ClassFileLoader.java b/group08/286060098/3-27/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..1d1927d217 --- /dev/null +++ b/group08/286060098/3-27/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,48 @@ +package com.coderising.jvm.loader; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import com.google.common.base.Joiner; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + private static final Joiner JOINER = Joiner.on(";").skipNulls(); + + public byte[] readBinaryCode(String className) throws FileNotFoundException { + byte[] codeBytes; + for (String path : clzPaths) { + String clzPath = path + className.replace(".", "/") + ".class"; + try { + byte[] buffer = new byte[1024]; + int size = 0; + int index = 0; + InputStream in = new FileInputStream(clzPath); + codeBytes = new byte[in.available()]; + while ((size = in.read(buffer)) != -1) { + for (int i = 0; i < size; i++) { + codeBytes[index++] = buffer[i]; + } + } + return codeBytes; + } catch (Exception e) { + + } + } + return null; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + return JOINER.join(clzPaths); + } + +} diff --git a/group08/286060098/3-27/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group08/286060098/3-27/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..c19a588f83 --- /dev/null +++ b/group08/286060098/3-27/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,80 @@ +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; + +import java.io.FileNotFoundException; + +public class ClassFileloaderTest { + + static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + 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() throws FileNotFoundException { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(ClassFileloaderTest.class.getResource("/").getPath()); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + @Test + public void testMagicNumber() throws FileNotFoundException { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(ClassFileloaderTest.class.getResource("/").getPath()); + 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 < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + +} diff --git a/group08/286060098/3-27/src/com/coderising/jvm/test/EmployeeV1.java b/group08/286060098/3-27/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..96da1ce697 --- /dev/null +++ b/group08/286060098/3-27/src/com/coderising/jvm/test/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrame.java b/group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..3a79c1d5b5 --- /dev/null +++ b/group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,142 @@ +package com.coding.basic.linklist; + +import java.util.Objects; + +/** + * 用双向链表实现LRU算法 + */ +@SuppressWarnings("unchecked") +public class LRUPageFrame { + + // 容量 + private int capacity; + + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param pagNum + * @return + */ + public void access(int pagNum) { + if (first == null) { + first = new Node(); + first.setPageNum(pagNum); + return; + } + if (last == null) { + last = new Node(); + last.pageNum = first.pageNum; + first.pageNum = pagNum; + first.next = last; + last.prev = first; + return; + } + addNode(pagNum); + } + + private void addNode(int pagNum) { + // 找得到 + Node node = findNode(pagNum); + if (node == null) { + node = new Node(); + node.setPageNum(first.getPageNum()); + first.pageNum = pagNum; + first.next.prev = node; + node.next = first.next; + first.next = node; + node.prev = first; + } else { + if (node.prev == null) { + return; + } else if (node.next == null) { + node.prev.next = null; + } else { + node.next.prev = node.prev; + node.prev.next = node.next; + } + node = new Node(); + node.pageNum = first.pageNum; + node.next = first.next; + first.next.prev = node; + node.prev = first; + first.next = node; + first.pageNum = pagNum; + } + Node tmp = first; + int i = 1; + while (tmp.next != null && i < capacity) { + tmp = tmp.next; + i++; + } + tmp.next = null; + last = tmp; + } + + private Node findNode(int pageNum) { + Node tmp = first; + while (tmp != null) { + if (Objects.equals(tmp.getPageNum(), pageNum)) { + return tmp; + } + tmp = tmp.next; + } + return null; + } + + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first; + while (node != null) { + buffer.append(node.getPageNum()); + node = node.next; + if (node != null) { + buffer.append(","); + } + } + return buffer.toString(); + } + + private static class Node { + + Node prev; + + Node next; + + int pageNum; + + Node() { + } + + public int getPageNum() { + return pageNum; + } + + public Node getNext() { + return next; + } + + public Node getPrev() { + return prev; + } + + public void setNext(Node next) { + this.next = next; + } + + public void setPageNum(int pageNum) { + this.pageNum = pageNum; + } + + public void setPrev(Node prev) { + this.prev = prev; + } + } + +} diff --git a/group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..4fcac1cdb3 --- /dev/null +++ b/group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,29 @@ +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/group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java b/group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..6c0b2dcade --- /dev/null +++ b/group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,154 @@ +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;// 链表尾 + private int length;// 链表长度 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + this.length = 0; + + } + + private Node findNode(int pageNum) { + for (Node pNode = first; pNode != null; pNode = pNode.next) { + if (pNode.pageNum == pageNum) { + return pNode; + } + } + + return null; + } + + private void ensureLength() { + while (length > capacity && last != null) { + last = last.prev; + length--; + } + + if (last == null) { + first = null; + } + else { + last.next = null; + } + } + + private void addFirstNode(Node pNode) { + if (pNode == null) { + return; + } + + pNode.next = first; + + if (first != null) { + first.prev = pNode; + } + + first = pNode; + + if (last == null) { + last = pNode; + } + + length++; + } + + private Node removeNode(Node pNode) { + if (pNode == null) { + return null; + } + + Node prevN = pNode.prev; + Node nextN = pNode.next; + + if (pNode == first) { + first = nextN; + } + if (pNode == last) { + last = prevN; + } + if (prevN != null) { + prevN.next = nextN; + } + if (nextN != null) { + nextN.prev = prevN; + } + + pNode.prev = null; + pNode.next = null; + length--; + + return pNode; + } + + private void addNewPage(int pageNum) { + Node pNode = new Node(); + pNode.pageNum = pageNum; + addFirstNode(pNode); + } + + private void movePageToFirst(Node pNode) { + if (pNode == null) { + return; + } + + addFirstNode(removeNode(pNode)); + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + Node pNode = findNode(pageNum); + if (pNode == null) { + addNewPage(pageNum); + ensureLength(); + return; + } + + movePageToFirst(pNode); + } + + + + 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/group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group08/619057560/4-2/code/data-structure/src/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/group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..47ca9dd42b --- /dev/null +++ b/group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,87 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + for (String path: clzPaths) { + String fileName = path + '/' + className.replace('.', '/') + ".class"; + System.out.println(fileName); + File file = new File(fileName); + if (file.exists()) { + return loadClassFile(fileName); + } + } + return null; + + + } + + private byte[] loadClassFile(String clzFileName) { + File file = new File(clzFileName); + int len; + int bufferLen = 100; + byte[] buffer = new byte[bufferLen]; + FileInputStream fis = null; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + fis = new FileInputStream(file); + while ((len = fis.read(buffer, 0, bufferLen)) >= 0) { + bos.write(buffer, 0, len); + } + return bos.toByteArray(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath_V1(){ + + return null; + } + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + for (String path: clzPaths) { + sb.append(path).append(";"); + } + sb.deleteCharAt(sb.length()-1); + return sb.toString(); + } + + + + + +} diff --git a/group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..a05534b210 --- /dev/null +++ b/group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,92 @@ +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 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + 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;ihttp://blog.csdn.net/qq1332479771/article/details/57597710 - -##121027265 ->https://github.com/Greastate/coding2017/blob/master/group08/121027265/0226/cpu_%E5%86%85%E5%AD%98_%E7%A1%AC%E7%9B%98_%E6%8C%87%E4%BB%A4%E4%B9%8B%E9%97%B4%E5%85%B3%E7%B3%BB.md - -##1425809544 ->http://blog.csdn.net/qq_25385555/article/details/60324265 - -##283677872 ->https://github.com/Greastate/coding2017/blob/master/group08/283677872/2-26/CPU%EF%BC%8C%E5%86%85%E5%AD%98%EF%BC%8C%E7%A1%AC%E7%9B%98%EF%BC%8C%E6%8C%87%E4%BB%A4%E5%85%B3%E7%B3%BB.pdf - -##286060098 ->https://github.com/Greastate/coding2017/blob/master/group08/286060098/2-26/blong/%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84.md - -##406166841 -https://github.com/Greastate/coding2017/blob/master/group08/406166841/2-26/CPU.md - -##529757467 ->https://github.com/Greastate/coding2017/blob/master/group08/529757467/2017-02-26%E4%BD%9C%E4%B8%9A/README.md - -##619057560 ->https://github.com/Greastate/coding2017/blob/master/group08/619057560/2-26/article/CPU%EF%BC%8C%E5%86%85%E5%AD%98%EF%BC%8C%E7%A1%AC%E7%9B%98%EF%BC%8C%E6%8C%87%E4%BB%A4%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB.pdf - -##649859235 -> http://note.youdao.com/noteshare?id=a0345eff655b1cfc5877cc267452eed0&sub=FE5CD301B3C742269D04973B0DD2393C - -##729770920 ->https://github.com/Greastate/coding2017/blob/master/group08/729770920/2-26/README.md - -##782476895 ->https://github.com/Greastate/coding2017/blob/master/group08/782476895/20170225/README.md - -#第二周文章 -##1425809544 ->http://m.blog.csdn.net/article/details?id=56674070 - -##1509102580 ->https://github.com/Greastate/coding2017/blob/master/group08/1509102580/3.5/%E6%96%87%E7%AB%A0-%E4%B8%80%E5%91%A8%E7%AC%94%E8%AE%B0 - -##286060098 ->http://www.jianshu.com/p/ccea84c2a6ba# - -##529757467 ->https://github.com/Greastate/coding2017/blob/master/group08/529757467/2017-03-05%E4%BD%9C%E4%B8%9A/README.md - -##619057560 ->https://github.com/Greastate/coding2017/blob/master/group08/619057560/3-5/article/%E7%A8%8B%E5%BA%8F%E7%9A%84%E8%BF%90%E8%A1%8C%E5%92%8C%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81.pdf - -##649859235 -> http://note.youdao.com/noteshare?id=1ad407f0dec5587138d9af273e491bca&sub=468E975854CE4B8F8CEF4D564E21842F - -##782476895 ->https://github.com/Greastate/coding2017/blob/master/group08/782476895/20170305/README.md - -#第三周文章 -##619057560 ->https://github.com/Greastate/coding2017/blob/master/group08/619057560/3-12/article/Java%E6%B5%81%E7%9A%84%E4%BB%8B%E7%BB%8D.pdf - -##649859235 -> http://note.youdao.com/noteshare?id=a0e00ce473692d46ac87881ad77c3b11&sub=C46D2B83C8074C6A8BF4C024F3B057D3 - -##529757467 ->http://www.jianshu.com/p/b773756f741f \ No newline at end of file diff --git "a/group08/\345\205\253\347\273\204\344\275\234\344\270\232\345\256\214\346\210\220\346\203\205\345\206\265.xlsx" "b/group08/\345\205\253\347\273\204\344\275\234\344\270\232\345\256\214\346\210\220\346\203\205\345\206\265.xlsx" deleted file mode 100644 index 46d6fa61e4..0000000000 Binary files "a/group08/\345\205\253\347\273\204\344\275\234\344\270\232\345\256\214\346\210\220\346\203\205\345\206\265.xlsx" and /dev/null differ diff --git a/group09/41689722.eulerlcs/2.code/jmr-01-aggregator/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-01-aggregator/pom.xml index b04166b31c..3edeb21d2e 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-01-aggregator/pom.xml +++ b/group09/41689722.eulerlcs/2.code/jmr-01-aggregator/pom.xml @@ -10,8 +10,11 @@ ../jmr-02-parent ../jmr-11-challenge - ../jmr-61-170226-collection - ../jmr-61-170305-litestruts - ../jmr-61-170312-multiThreadDownload + ../jmr-51-liuxin-question + ../jmr-52-liuxin-answer + ../jmr-61-collection + ../jmr-62-litestruts + ../jmr-63-download + ../jmr-64-minijvm \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/sc.class b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/sc.class new file mode 100644 index 0000000000..4b35c9da34 Binary files /dev/null and b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/sc.class differ diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/shoppingcart.data b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/shoppingcart.data new file mode 100644 index 0000000000..336fd732b4 Binary files /dev/null and b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/shoppingcart.data differ diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/classloader/core/NetworkClassLoader.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/classloader/core/NetworkClassLoader.java index 0241e92a5c..c0f524a1b4 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/classloader/core/NetworkClassLoader.java +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/classloader/core/NetworkClassLoader.java @@ -5,9 +5,9 @@ import java.net.URL; public class NetworkClassLoader extends ClassLoader { - + private String rootUrl; - + public NetworkClassLoader(String rootUrl) { this.rootUrl = rootUrl; } @@ -16,12 +16,11 @@ protected Class findClass(String name) throws ClassNotFoundException { byte[] classData = getClassData(name); if (classData == null) { throw new ClassNotFoundException(); - } - else { + } else { return defineClass(name, classData, 0, classData.length); } } - + private byte[] getClassData(String className) { String path = classNameToPath(className); try { @@ -40,9 +39,8 @@ private byte[] getClassData(String className) { } return null; } - + private String classNameToPath(String className) { - return rootUrl + "/" - + className.replace('.', '/') + ".class"; + return rootUrl + "/" + className.replace('.', '/') + ".class"; } } diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170205.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170205.java new file mode 100644 index 0000000000..b18db9d387 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170205.java @@ -0,0 +1,132 @@ +package com.github.eulerlcs.jmr.challenge.zzz.master170219; + +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; + +public class Try170205 { + public static void main(String[] args) throws Exception { + task94(); + task93(); + task84(); + task83(); + task65(); + task64(); + + ArrayList list = new ArrayList(); + show(list); + } + + public static void show(ArrayList list) { + // .... + } + + public static void task64() { + DataInputStream dis = null; + double price = 0; + int count = 0; + double sum = 0; + String disp = ""; + + try { + dis = new DataInputStream(new FileInputStream("data/shoppingcart.data")); + while (dis.available() > 0) { + price = dis.readDouble(); + count = dis.readInt(); + disp = dis.readUTF(); + System.out.println(disp); + sum += price * count; + } + + System.out.println("sum=" + sum); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + dis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + + public static void task65() { + DataInputStream dis = null; + byte[] magic = { (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe }; + boolean ret = true; + + try { + dis = new DataInputStream(new FileInputStream("data/sc.class")); + for (int i = 0; i < 4; i++) { + if (magic[i] != dis.readByte()) { + ret = false; + break; + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + dis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if (ret) { + System.out.println("it is cafebabe"); + } else { + System.out.println("it is not cafebabe"); + } + } + + public static void task83() throws Exception { + Class clazz = Class.forName("shoppingcart.Employee"); + Constructor ct = clazz.getConstructor(String.class, int.class); + Object obj = ct.newInstance("ref", 22); + + Method sayHello = clazz.getDeclaredMethod("sayHello"); + sayHello.invoke(obj); + + Method getID = clazz.getDeclaredMethod("getID"); + getID.setAccessible(true); + String ids = (String) getID.invoke(obj); + System.out.println("getID=" + ids); + + Field[] flds = clazz.getDeclaredFields(); + for (Field fld : flds) { + System.out.println(fld); + } + } + + public static void task84() throws Exception { + ArrayList list = new ArrayList<>(); + list.add(3232); + + Class clazz = ArrayList.class; + + Field elementDataField = clazz.getDeclaredField("elementData"); + elementDataField.setAccessible(true); + Object[] elementData = (Object[]) elementDataField.get(list); + if (elementData.length > 1) { + elementData[1] = "added by reflection"; + } + } + + public static void task93() { + ArrayList list1 = new ArrayList(); + ArrayList list2 = new ArrayList(); + System.out.println(list1.getClass().equals(list2.getClass())); + } + + public static void task94() { + ArrayList numbers = new ArrayList(); + numbers.add(new Integer(10)); + numbers.add(new Double(10.0d)); + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170212.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170212.java new file mode 100644 index 0000000000..5492441572 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170212.java @@ -0,0 +1,34 @@ +package com.github.eulerlcs.jmr.challenge.zzz.master170219; + +public class Try170212 { + + public static void main(String[] args) { + t28(); + } + + public static void changeStr(String str) { + str = "welcome"; + } + + public static void t28() { + String str = "1234"; + changeStr(str); + System.out.println(str); + } + + public static void t34() { + Try170212 x = new Try170212(); + Try170212.Hello obj = x.new Hello(""); + obj.msg += ",World!"; + System.out.println(obj.msg); + } + + class Hello { + public String msg = "Hello"; + + public Hello(String msg) { + this.msg = msg; + } + } + +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170219.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170219.java new file mode 100644 index 0000000000..559dc44a7c --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170219.java @@ -0,0 +1,47 @@ +package com.github.eulerlcs.jmr.challenge.zzz.master170219; + +import java.util.ArrayList; +import java.util.Date; + +public class Try170219 { + public static void main(String[] args) { + Integer[] a = new Integer[10]; + case003(a); + } + + public static void case001() { + Fruit f = new Apple(); + f.setDate(new Date()); + } + + public static void case002() { + ArrayList list1 = new ArrayList(); + ArrayList list2 = new ArrayList(); + System.out.println(list1.getClass().equals(list2.getClass())); + } + + public static void case003(Number[] n) { + // nop + } + +} + +class Fruit { + public void setDate(Object d) { + System.out.println("Fruit.setDate(Object d)"); + } + + // public void setDate2(Object d) { + // System.out.println("Fruit.setDate(Object d)"); + // } +} + +class Apple extends Fruit { + public void setDate(Date d) { + System.out.println("Apple.setDate(Date d)"); + } + + public void setDate2(Date d) { + System.out.println("Apple.setDate(Date d)"); + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/BatchDownloadFile.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/BatchDownloadFile.java new file mode 100644 index 0000000000..48b4f67670 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/BatchDownloadFile.java @@ -0,0 +1,227 @@ +package com.hoo.download; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import com.hoo.entity.DownloadInfo; +import com.hoo.util.LogUtils; + +/** + * function: 分批量下载文件 + * + * @author hoojo + * @createDate 2011-9-22 下午05:51:54 + * @file BatchDownloadFile.java + * @package com.hoo.download + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public class BatchDownloadFile implements Runnable { + // 下载文件信息 + private DownloadInfo downloadInfo; + // 一组开始下载位置 + private long[] startPos; + // 一组结束下载位置 + private long[] endPos; + // 休眠时间 + private static final int SLEEP_SECONDS = 500; + // 子线程下载 + private DownloadFile[] fileItem; + // 文件长度 + private int length; + // 是否第一个文件 + private boolean first = true; + // 是否停止下载 + private boolean stop = false; + // 临时文件信息 + private File tempFile; + + public BatchDownloadFile(DownloadInfo downloadInfo) { + this.downloadInfo = downloadInfo; + String tempPath = this.downloadInfo.getFilePath() + File.separator + downloadInfo.getFileName() + ".position"; + tempFile = new File(tempPath); + // 如果存在读入点位置的文件 + if (tempFile.exists()) { + first = false; + // 就直接读取内容 + try { + readPosInfo(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + // 数组的长度就要分成多少段的数量 + startPos = new long[downloadInfo.getSplitter()]; + endPos = new long[downloadInfo.getSplitter()]; + } + } + + @Override + public void run() { + // 首次下载,获取下载文件长度 + if (first) { + length = this.getFileSize();// 获取文件长度 + if (length == -1) { + LogUtils.log("file length is know!"); + stop = true; + } else if (length == -2) { + LogUtils.log("read file length is error!"); + stop = true; + } else if (length > 0) { + /** + * eg start: 1, 3, 5, 7, 9 end: 3, 5, 7, 9, length + */ + for (int i = 0, len = startPos.length; i < len; i++) { + int size = i * (length / len); + startPos[i] = size; + + // 设置最后一个结束点的位置 + if (i == len - 1) { + endPos[i] = length; + } else { + size = (i + 1) * (length / len); + endPos[i] = size; + } + LogUtils.log("start-end Position[" + i + "]: " + startPos[i] + "-" + endPos[i]); + } + } else { + LogUtils.log("get file length is error, download is stop!"); + stop = true; + } + } + + // 子线程开始下载 + if (!stop) { + // 创建单线程下载对象数组 + fileItem = new DownloadFile[startPos.length];// startPos.length = + // downloadInfo.getSplitter() + for (int i = 0; i < startPos.length; i++) { + try { + // 创建指定个数单线程下载对象,每个线程独立完成指定块内容的下载 + fileItem[i] = new DownloadFile(downloadInfo.getUrl(), + this.downloadInfo.getFilePath() + File.separator + downloadInfo.getFileName(), startPos[i], + endPos[i], i); + fileItem[i].start();// 启动线程,开始下载 + LogUtils.log("Thread: " + i + ", startPos: " + startPos[i] + ", endPos: " + endPos[i]); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // 循环写入下载文件长度信息 + while (!stop) { + try { + writePosInfo(); + LogUtils.log("downloading……"); + Thread.sleep(SLEEP_SECONDS); + stop = true; + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + for (int i = 0; i < startPos.length; i++) { + if (!fileItem[i].isDownloadOver()) { + stop = false; + break; + } + } + } + LogUtils.info("Download task is finished!"); + } + } + + /** + * 将写入点数据保存在临时文件中 + * + * @author hoojo + * @createDate 2011-9-23 下午05:25:37 + * @throws IOException + */ + private void writePosInfo() throws IOException { + DataOutputStream dos = new DataOutputStream(new FileOutputStream(tempFile)); + dos.writeInt(startPos.length); + for (int i = 0; i < startPos.length; i++) { + dos.writeLong(fileItem[i].getStartPos()); + dos.writeLong(fileItem[i].getEndPos()); + // LogUtils.info("[" + fileItem[i].getStartPos() + "#" + + // fileItem[i].getEndPos() + "]"); + } + dos.close(); + } + + /** + * function:读取写入点的位置信息 + * + * @author hoojo + * @createDate 2011-9-23 下午05:30:29 + * @throws IOException + */ + private void readPosInfo() throws IOException { + DataInputStream dis = new DataInputStream(new FileInputStream(tempFile)); + int startPosLength = dis.readInt(); + startPos = new long[startPosLength]; + endPos = new long[startPosLength]; + for (int i = 0; i < startPosLength; i++) { + startPos[i] = dis.readLong(); + endPos[i] = dis.readLong(); + } + dis.close(); + } + + /** + * function: 获取下载文件的长度 + * + * @author hoojo + * @createDate 2011-9-26 下午12:15:08 + * @return + */ + private int getFileSize() { + int fileLength = -1; + try { + URL url = new URL(this.downloadInfo.getUrl()); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + DownloadFile.setHeader(conn); + + int stateCode = conn.getResponseCode(); + // 判断http status是否为HTTP/1.1 206 Partial Content或者200 OK + if (stateCode != HttpURLConnection.HTTP_OK && stateCode != HttpURLConnection.HTTP_PARTIAL) { + LogUtils.log("Error Code: " + stateCode); + return -2; + } else if (stateCode >= 400) { + LogUtils.log("Error Code: " + stateCode); + return -2; + } else { + // 获取长度 + fileLength = conn.getContentLength(); + LogUtils.log("FileLength: " + fileLength); + } + + // 读取文件长度 + /* + * for (int i = 1; ; i++) { String header = + * conn.getHeaderFieldKey(i); if (header != null) { if + * ("Content-Length".equals(header)) { fileLength = + * Integer.parseInt(conn.getHeaderField(i)); break; } } else { + * break; } } + */ + + DownloadFile.printHeader(conn); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return fileLength; + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/DownloadFile.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/DownloadFile.java new file mode 100644 index 0000000000..784efa1d88 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/DownloadFile.java @@ -0,0 +1,176 @@ +package com.hoo.download; + +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 com.hoo.util.LogUtils; + +/** + * function: 单线程下载文件 + * + * @author hoojo + * @createDate 2011-9-22 下午02:55:10 + * @file DownloadFile.java + * @package com.hoo.download + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public class DownloadFile extends Thread { + + // 下载文件url + private String url; + // 下载文件起始位置 + private long startPos; + // 下载文件结束位置 + private long endPos; + // 线程id + private int threadId; + + // 下载是否完成 + private boolean isDownloadOver = false; + + private SaveItemFile itemFile; + + private static final int BUFF_LENGTH = 1024 * 8; + + /** + * @param url + * 下载文件url + * @param name + * 文件名称 + * @param startPos + * 下载文件起点 + * @param endPos + * 下载文件结束点 + * @param threadId + * 线程id + * @throws IOException + */ + public DownloadFile(String url, String name, long startPos, long endPos, int threadId) throws IOException { + super(); + this.url = url; + this.startPos = startPos; + this.endPos = endPos; + this.threadId = threadId; + // 分块下载写入文件内容 + this.itemFile = new SaveItemFile(name, startPos); + } + + @Override + public void run() { + while (endPos > startPos && !isDownloadOver) { + try { + URL url = new URL(this.url); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + // 设置连接超时时间为10000ms + conn.setConnectTimeout(10000); + // 设置读取数据超时时间为10000ms + conn.setReadTimeout(10000); + + setHeader(conn); + + String property = "bytes=" + startPos + "-"; + conn.setRequestProperty("RANGE", property); + + // 输出log信息 + LogUtils.log("开始 " + threadId + ":" + property + endPos); + // printHeader(conn); + + // 获取文件输入流,读取文件内容 + InputStream is = conn.getInputStream(); + + byte[] buff = new byte[BUFF_LENGTH]; + int length = -1; + LogUtils.log("#start#Thread: " + threadId + ", startPos: " + startPos + ", endPos: " + endPos); + while ((length = is.read(buff)) > 0 && startPos < endPos && !isDownloadOver) { + // 写入文件内容,返回最后写入的长度 + startPos += itemFile.write(buff, 0, length); + } + LogUtils.log("#over#Thread: " + threadId + ", startPos: " + startPos + ", endPos: " + endPos); + LogUtils.log("Thread " + threadId + " is execute over!"); + this.isDownloadOver = true; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (itemFile != null) { + itemFile.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + if (endPos < startPos && !isDownloadOver) { + LogUtils.log("Thread " + threadId + " startPos > endPos, not need download file !"); + this.isDownloadOver = true; + } + if (endPos == startPos && !isDownloadOver) { + LogUtils.log("Thread " + threadId + " startPos = endPos, not need download file !"); + this.isDownloadOver = true; + } + } + + /** + * function: 打印下载文件头部信息 + * + * @author hoojo + * @createDate 2011-9-22 下午05:44:35 + * @param conn + * HttpURLConnection + */ + public static void printHeader(URLConnection conn) { + int i = 1; + while (true) { + String header = conn.getHeaderFieldKey(i); + i++; + if (header != null) { + LogUtils.info(header + ":" + conn.getHeaderField(i)); + } else { + break; + } + } + } + + /** + * function: 设置URLConnection的头部信息,伪装请求信息 + * + * @author hoojo + * @createDate 2011-9-28 下午05:29:43 + * @param con + */ + public static void setHeader(URLConnection conn) { + conn.setRequestProperty("User-Agent", + "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3"); + conn.setRequestProperty("Accept-Language", "en-us,en;q=0.7,zh-cn;q=0.3"); + conn.setRequestProperty("Accept-Encoding", "utf-8"); + conn.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); + conn.setRequestProperty("Keep-Alive", "300"); + conn.setRequestProperty("connnection", "keep-alive"); + conn.setRequestProperty("If-Modified-Since", "Fri, 02 Jan 2009 17:00:05 GMT"); + conn.setRequestProperty("If-None-Match", "\"1261d8-4290-df64d224\""); + conn.setRequestProperty("Cache-conntrol", "max-age=0"); + conn.setRequestProperty("Referer", "https://www.github.com"); + } + + public boolean isDownloadOver() { + return isDownloadOver; + } + + public long getStartPos() { + return startPos; + } + + public long getEndPos() { + return endPos; + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/SaveItemFile.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/SaveItemFile.java new file mode 100644 index 0000000000..c0dcb62ac3 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/SaveItemFile.java @@ -0,0 +1,68 @@ +package com.hoo.download; + +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * function: 写入文件、保存文件 + * + * @author hoojo + * @createDate 2011-9-21 下午05:44:02 + * @file SaveItemFile.java + * @package com.hoo.download + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public class SaveItemFile { + // 存储文件 + private RandomAccessFile itemFile; + + public SaveItemFile() throws IOException { + this("", 0); + } + + /** + * @param name + * 文件路径、名称 + * @param pos + * 写入点位置 position + * @throws IOException + */ + public SaveItemFile(String name, long pos) throws IOException { + itemFile = new RandomAccessFile(name, "rw"); + // 在指定的pos位置开始写入数据 + itemFile.seek(pos); + } + + /** + * function: 同步方法写入文件 + * + * @author hoojo + * @createDate 2011-9-26 下午12:21:22 + * @param buff + * 缓冲数组 + * @param start + * 起始位置 + * @param length + * 长度 + * @return + */ + public synchronized int write(byte[] buff, int start, int length) { + int i = -1; + try { + itemFile.write(buff, start, length); + i = length; + } catch (IOException e) { + e.printStackTrace(); + } + return i; + } + + public void close() throws IOException { + if (itemFile != null) { + itemFile.close(); + } + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/entity/DownloadInfo.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/entity/DownloadInfo.java new file mode 100644 index 0000000000..7ef4ba5477 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/entity/DownloadInfo.java @@ -0,0 +1,125 @@ + +package com.hoo.entity; + +/** + * function: 下载文件信息类 + * + * @author hoojo + * @createDate 2011-9-21 下午05:14:58 + * @file DownloadInfo.java + * @package com.hoo.entity + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public class DownloadInfo { + // 下载文件url + private String url; + // 下载文件名称 + private String fileName; + // 下载文件路径 + private String filePath; + // 分成多少段下载, 每一段用一个线程完成下载 + private int splitter; + + // 下载文件默认保存路径 + private final static String FILE_PATH = "C:/temp"; + // 默认分块数、线程数 + private final static int SPLITTER_NUM = 5; + + public DownloadInfo() { + super(); + } + + /** + * @param url + * 下载地址 + */ + public DownloadInfo(String url) { + this(url, null, null, SPLITTER_NUM); + } + + /** + * @param url + * 下载地址url + * @param splitter + * 分成多少段或是多少个线程下载 + */ + public DownloadInfo(String url, int splitter) { + this(url, null, null, splitter); + } + + /*** + * @param url + * 下载地址 + * @param fileName + * 文件名称 + * @param filePath + * 文件保存路径 + * @param splitter + * 分成多少段或是多少个线程下载 + */ + public DownloadInfo(String url, String fileName, String filePath, int splitter) { + super(); + if (url == null || "".equals(url)) { + throw new RuntimeException("url is not null!"); + } + this.url = url; + this.fileName = (fileName == null || "".equals(fileName)) ? getFileName(url) : fileName; + this.filePath = (filePath == null || "".equals(filePath)) ? FILE_PATH : filePath; + this.splitter = (splitter < 1) ? SPLITTER_NUM : splitter; + } + + /** + * function: 通过url获得文件名称 + * + * @author hoojo + * @createDate 2011-9-30 下午05:00:00 + * @param url + * @return + */ + private String getFileName(String url) { + return url.substring(url.lastIndexOf("/") + 1, url.length()); + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + if (url == null || "".equals(url)) { + throw new RuntimeException("url is not null!"); + } + this.url = url; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = (fileName == null || "".equals(fileName)) ? getFileName(url) : fileName; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = (filePath == null || "".equals(filePath)) ? FILE_PATH : filePath; + } + + public int getSplitter() { + return splitter; + } + + public void setSplitter(int splitter) { + this.splitter = (splitter < 1) ? SPLITTER_NUM : splitter; + } + + @Override + public String toString() { + return this.url + "#" + this.fileName + "#" + this.filePath + "#" + this.splitter; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtils.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtils.java new file mode 100644 index 0000000000..3ca0384319 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtils.java @@ -0,0 +1,40 @@ +package com.hoo.util; + +import com.hoo.download.BatchDownloadFile; +import com.hoo.entity.DownloadInfo; + +/** + * function: 分块多线程下载工具类 + * + * @author hoojo + * @createDate 2011-9-28 下午05:22:18 + * @file DownloadUtils.java + * @package com.hoo.util + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public abstract class DownloadUtils { + + public static void download(String url) { + DownloadInfo bean = new DownloadInfo(url); + LogUtils.info(bean); + BatchDownloadFile down = new BatchDownloadFile(bean); + new Thread(down).start(); + } + + public static void download(String url, int threadNum) { + DownloadInfo bean = new DownloadInfo(url, threadNum); + LogUtils.info(bean); + BatchDownloadFile down = new BatchDownloadFile(bean); + new Thread(down).start(); + } + + public static void download(String url, String fileName, String filePath, int threadNum) { + DownloadInfo bean = new DownloadInfo(url, fileName, filePath, threadNum); + LogUtils.info(bean); + BatchDownloadFile down = new BatchDownloadFile(bean); + new Thread(down).start(); + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtilsTest.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtilsTest.java new file mode 100644 index 0000000000..562a0ec047 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtilsTest.java @@ -0,0 +1,39 @@ +/** + * copy from http://blog.csdn.net/ibm_hoojo/article/details/6838222 + */ +package com.hoo.util; + +/** + * function: 下载测试 + * + * @author hoojo + * @createDate 2011-9-23 下午05:49:46 + * @file TestDownloadMain.java + * @package com.hoo.download + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public class DownloadUtilsTest { + public static void main(String[] args) { + /* + * DownloadInfo bean = new DownloadInfo( + * "http://i7.meishichina.com/Health/UploadFiles/201109/2011092116224363.jpg" + * ); System.out.println(bean); BatchDownloadFile down = new + * BatchDownloadFile(bean); new Thread(down).start(); + */ + + // DownloadUtils.download("http://i7.meishichina.com/Health/UploadFiles/201109/2011092116224363.jpg"); + DownloadUtils.download("https://github.com/dracome/coding2017/archive/master.zip", 5); + + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + int i = 3; + System.out.println(i); + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/LogUtils.java b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/LogUtils.java new file mode 100644 index 0000000000..62d48bd0f9 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/LogUtils.java @@ -0,0 +1,40 @@ +package com.hoo.util; + +/** + * function: 日志工具类 + * + * @author hoojo + * @createDate 2011-9-21 下午05:21:27 + * @file LogUtils.java + * @package com.hoo.util + * @project MultiThreadDownLoad + * @blog http://blog.csdn.net/IBM_hoojo + * @email hoojo_@126.com + * @version 1.0 + */ +public abstract class LogUtils { + + public static void log(Object message) { + System.err.println(message); + } + + public static void log(String message) { + System.err.println(message); + } + + public static void log(int message) { + System.err.println(message); + } + + public static void info(Object message) { + System.out.println(message); + } + + public static void info(String message) { + System.out.println(message); + } + + public static void info(int message) { + System.out.println(message); + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/Connection.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/Connection.java similarity index 91% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/Connection.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/Connection.java index d0037a877b..76dc0f3a40 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/Connection.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/Connection.java @@ -1,4 +1,4 @@ -package com.github.eulerlcs.jmr.multiDL.api; +package com.coderising.download.api; import java.io.IOException; diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionException.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/ConnectionManager.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionManager.java similarity index 80% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/ConnectionManager.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionManager.java index a350054dd4..787984f170 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/ConnectionManager.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionManager.java @@ -1,4 +1,4 @@ -package com.github.eulerlcs.jmr.multiDL.api; +package com.coderising.download.api; public interface ConnectionManager { /** diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/DownloadListener.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/DownloadThread.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/DownloadThread.java new file mode 100644 index 0000000000..ba94bee146 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/DownloadThread.java @@ -0,0 +1,21 @@ +package com.coderising.download.core; + +import com.coderising.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/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/FileDownloader.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/FileDownloader.java similarity index 87% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/FileDownloader.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/FileDownloader.java index fca00437d7..23ee19ab02 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/FileDownloader.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/FileDownloader.java @@ -1,9 +1,9 @@ -package com.github.eulerlcs.jmr.multiDL; +package com.coderising.download.core; -import com.github.eulerlcs.jmr.multiDL.api.Connection; -import com.github.eulerlcs.jmr.multiDL.api.ConnectionException; -import com.github.eulerlcs.jmr.multiDL.api.ConnectionManager; -import com.github.eulerlcs.jmr.multiDL.api.DownloadListener; +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 { @@ -15,6 +15,7 @@ public class FileDownloader { public FileDownloader(String _url) { this.url = _url; + } public void execute() { @@ -35,6 +36,7 @@ public void execute() { // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 Connection conn = null; try { + conn = cm.open(this.url); int length = conn.getContentLength(); @@ -48,6 +50,7 @@ public void execute() { conn.close(); } } + } public void setListener(DownloadListener listener) { @@ -61,4 +64,5 @@ public void setConnectionManager(ConnectionManager ucm) { public DownloadListener getListener() { return this.listener; } + } diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionImpl.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionImpl.java similarity index 73% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionImpl.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionImpl.java index 613c692750..1831118927 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionImpl.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionImpl.java @@ -1,8 +1,8 @@ -package com.github.eulerlcs.jmr.multiDL.impl; +package com.coderising.download.impl; import java.io.IOException; -import com.github.eulerlcs.jmr.multiDL.api.Connection; +import com.coderising.download.api.Connection; public class ConnectionImpl implements Connection { @@ -22,4 +22,5 @@ public int getContentLength() { public void close() { } + } diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..6585b835c4 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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 null; + } + +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..7347ab0a88 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.loader; + +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + return null; + } + + public void addClassPath(String path) { + } + + public String getClassPath() { + return null; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/LoginAction.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..5f41f42c62 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/LoginAction.java @@ -0,0 +1,42 @@ +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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/Struts.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..5ad5ccb352 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/Struts.java @@ -0,0 +1,30 @@ +package com.coderising.litestruts; + +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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/View.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..f1e7fcfa19 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/View.java @@ -0,0 +1,26 @@ +package com.coderising.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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/BinaryTreeNode.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..2f944d3b91 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/BinaryTreeNode.java @@ -0,0 +1,37 @@ +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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Iterator.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..f30dfc8edf --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Iterator.java @@ -0,0 +1,8 @@ +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + + public Object next(); + +} diff --git a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/List.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/List.java similarity index 83% rename from group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/List.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/List.java index 5226796141..03fa879b2e 100644 --- a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/List.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/List.java @@ -1,4 +1,4 @@ -package com.stackwei.DataStructure; +package com.coding.basic; public interface List { public void add(Object o); diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Queue.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Queue.java new file mode 100644 index 0000000000..b2908512c5 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Stack.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Stack.java new file mode 100644 index 0000000000..988b174e55 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Stack.java @@ -0,0 +1,26 @@ +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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayList.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayList.java new file mode 100644 index 0000000000..81dfe5bdfe --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayList.java @@ -0,0 +1,36 @@ +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayUtil.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..0e8e077db7 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,96 @@ +package com.coding.basic.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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..f6732b68e8 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,50 @@ +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) { + } + + @Override + 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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LinkedList.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..6c8b4a3315 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,129 @@ +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class LinkedList implements List { + + private Node head; + + 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 void addFirst(Object o) { + + } + + public void addLast(Object o) { + + } + + public Object removeFirst() { + return null; + } + + public Object removeLast() { + return null; + } + + public Iterator iterator() { + return null; + } + + private static class Node { + Object data; + Node next; + + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 + * + */ + public void removeFirstHalf() { + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int 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) { + 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; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/resources/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/resources/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/resources/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/test/java/com/github/eulerlcs/jmr/multiDL/FileDownloaderTest.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/download/core/FileDownloaderTest.java similarity index 80% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/test/java/com/github/eulerlcs/jmr/multiDL/FileDownloaderTest.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/download/core/FileDownloaderTest.java index cfb3274124..8e171cff93 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/test/java/com/github/eulerlcs/jmr/multiDL/FileDownloaderTest.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/download/core/FileDownloaderTest.java @@ -1,12 +1,12 @@ -package com.github.eulerlcs.jmr.multiDL; +package com.coderising.download.core; import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.github.eulerlcs.jmr.multiDL.api.ConnectionManager; -import com.github.eulerlcs.jmr.multiDL.api.DownloadListener; -import com.github.eulerlcs.jmr.multiDL.impl.ConnectionManagerImpl; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; public class FileDownloaderTest { boolean downloadFinished = false; @@ -21,6 +21,7 @@ public void tearDown() throws Exception { @Test public void testDownload() { + String url = "http://localhost:8080/test.jpg"; FileDownloader downloader = new FileDownloader(url); @@ -33,6 +34,7 @@ public void testDownload() { public void notifyFinished() { downloadFinished = true; } + }); downloader.execute(); @@ -47,7 +49,8 @@ public void notifyFinished() { e.printStackTrace(); } } - System.out.println("下载完成!"); + } + } diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..d43e4e5d54 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java @@ -0,0 +1,76 @@ +package com.coderising.jvm.loader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + 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 < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/EmployeeV1.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..2b80092ecb --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/EmployeeV1.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.loader; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts/StrutsTest.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..f2426db6ea --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,38 @@ +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/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coding/basic/linklist/LRUPageFrameTest.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..ff765f90b1 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,27 @@ +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/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/test/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/resources/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/test/resources/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/resources/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/basic/LinkedList.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/basic/LinkedList.java new file mode 100644 index 0000000000..5894d89630 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/basic/LinkedList.java @@ -0,0 +1,449 @@ +package com.coderising.basic; + +import java.util.Arrays; +import java.util.NoSuchElementException; +import java.util.Stack; + +public class LinkedList implements List { + + private Node head; + private int size; + + public LinkedList() { + size = 0; + head = null; + } + + public void add(Object o) { + Node node = new Node(o); + if (head == null) { + head = node; + } else { + // p为游标 从头遍历到尾 + Node p = head; + while (p.next != null) { + p = p.next; + } + p.next = node; + } + size++; + } + + public void add(int index, Object o) { + // 判断不为空链表 + if (head != null) { + Node p = head; + int k = 0; + // 扫描单链表查找第index-1个节点 + while (k < index - 1 && p.next != null) { + k++; + p = p.next; + } + // 判断是否找到第index-1个节点 + if (p != null) { + Node node = new Node(o); + node.next = p.next; + p.next = node; + } + size++; + } + } + + public Object get(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } else { + Node p = head; + int k = 0; + while (k < index && p.next != null) { + k++; + p = p.next; + } + return p.data; + } + } + + 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) { + Node node = new Node(o); + node.next = head; + head = node; + size++; + } + + public void addLast(Object o) { + Node node = new Node(o); + if (head == null) { + head = node; + } else { + Node p = head; + while (p.next != null) { + p = p.next; + } + p.next = node; + } + size++; + } + + public Object removeFirst() { + if (head == null) { + throw new NoSuchElementException(); + } + Node node = head; + head = node.next; + size--; + return node.data; + } + + public Object removeLast() { + if (head == null) { + throw new NoSuchElementException(); + } else { + Node p = head; + int k = 0; + while (k < size - 1 && p.next != null) { + k++; + p = p.next; + } + Node last = p.next; + p.next = null; + size--; + return last.data; + } + } + + private static class Node { + Object data; + Node next; + + private Node(Object o) { + this.data = o; + this.next = null; + } + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + + if (null == head || null == head.next) { + return; + } + Stack s = new Stack(); + + Node currentNode = head; + while (currentNode != null) { + + s.push(currentNode); + + Node nextNode = currentNode.next; + currentNode.next = null; // 把链接断开 + currentNode = nextNode; + } + + head = s.pop(); + + currentNode = head; + while (!s.isEmpty()) { + Node nextNode = s.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++; + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = + * 11->101->201->301->401->501->601->701 listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + + int[] arr = new int[list.size()]; + + for (int i = 0; i < list.size(); i++) { + arr[i] = (int) this.get((int) list.get(i)); + } + return arr; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + for (int i = 0; i < list.size(); i++) { + this.remove(list.get(i)); + } + } + + /** + * 传入数据删除节点 + * + * @param obj + */ + public void remove(Object obj) { + if (head == null) { + throw new RuntimeException("LinkedList is empty!"); + } + // 如果要删除的结点是第一个,则把下一个结点赋值给第一个结点 + if (head.data.equals(obj)) { + head = head.next; + size--; + } else { + Node pre = head; // 上一节点 + Node cur = head.next; // 当前结点 + while (cur != null) { + if (cur.data.equals(obj)) { + pre.next = cur.next; + size--; + } + pre = pre.next; + cur = cur.next; + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (head == null) { + throw new RuntimeException("LinkedList is empty!"); + } + + Node pre = head; + Node cur = head; + while (cur.next != null) { + cur = cur.next; + Object data = pre.data; + while (cur.data == data) { + if (cur.next == null) { + pre.next = null; + break; + } + pre.next = cur.next; + size--; + cur = cur.next; + if (cur == null) { + break; + } + } + pre = pre.next; + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + if (head == null) { + return; + } + + Node node = head; + int start = -1; + int end = -1; + int i = 0; + while (node != null) { + if ((start == -1) && (int) node.data <= min) { + start = i; + } + if ((int) node.data >= max) { + end = i; + break; + } + node = node.next; + i++; + } + + if (start == -1) { + start = 0; + } + if (end == -1) { + end = size; + } + this.remove(start, end - start); + + /* + * if(head == null){ throw new RuntimeException("LinkedList is empty!"); + * }else{ Node q = head; //头判断 if((int)q.data>min && (int)q.datamin && + * (int)p.data 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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..5e98063eaa --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Configuration.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Configuration.java new file mode 100644 index 0000000000..5b0f60c148 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Configuration.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ConfigurationException.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..97e286827f --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/LoginAction.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..5f41f42c62 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/LoginAction.java @@ -0,0 +1,42 @@ +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ReflectionUtil.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..1ba13d5245 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,120 @@ +package com.coderising.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; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Struts.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..b3fe556ebc --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Struts.java @@ -0,0 +1,56 @@ +package com.coderising.litestruts; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/View.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..f1e7fcfa19 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/View.java @@ -0,0 +1,26 @@ +package com.coderising.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/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/resources/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/resources/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/basic/LinkedListTest.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/basic/LinkedListTest.java new file mode 100644 index 0000000000..953a9a215b --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/basic/LinkedListTest.java @@ -0,0 +1,197 @@ +package com.coderising.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class LinkedListTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testReverse() { + LinkedList l = new LinkedList(); + + Assert.assertEquals("[]", l.toString()); + + l.add(1); + l.reverse(); + Assert.assertEquals("[1]", l.toString()); + + l.add(2); + l.add(3); + l.add(4); + + l.reverse(); + Assert.assertEquals("[4,3,2,1]", l.toString()); + } + + @Test + public void testRemoveFirstHalf() { + { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.removeFirstHalf(); + Assert.assertEquals("[3,4]", linkedList.toString()); + } + { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.add(5); + linkedList.removeFirstHalf(); + Assert.assertEquals("[3,4,5]", linkedList.toString()); + } + } + + @Test + public void testRemoveIntInt() { + { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.remove(0, 2); + Assert.assertEquals("[3,4]", linkedList.toString()); + } + { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.remove(3, 2); + Assert.assertEquals("[1,2,3]", linkedList.toString()); + } + { + LinkedList linkedList = new LinkedList(); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.remove(2, 2); + Assert.assertEquals("[1,2]", linkedList.toString()); + } + } + + @Test + public void testGetElements() { + LinkedList linkedList = new LinkedList(); + linkedList.add(11); + linkedList.add(101); + linkedList.add(201); + linkedList.add(301); + linkedList.add(401); + linkedList.add(501); + linkedList.add(601); + linkedList.add(701); + LinkedList list = new LinkedList(); + list.add(1); + list.add(3); + list.add(4); + list.add(6); + Assert.assertArrayEquals(new int[] { 101, 301, 401, 601 }, linkedList.getElements(list)); + } + + @Test + public void testSubtract() { + LinkedList list1 = new LinkedList(); + list1.add(101); + list1.add(201); + list1.add(301); + list1.add(401); + list1.add(501); + list1.add(601); + list1.add(701); + + LinkedList list2 = new LinkedList(); + + list2.add(101); + list2.add(201); + list2.add(301); + list2.add(401); + list2.add(501); + + list1.subtract(list2); + + Assert.assertEquals("[601,701]", list1.toString()); + } + + @Test + public void testRemoveDuplicateValues() { + LinkedList list = new LinkedList(); + list.add(1); + list.add(1); + list.add(2); + list.add(2); + list.add(3); + list.add(5); + list.add(5); + list.add(6); + list.removeDuplicateValues(); + + Assert.assertEquals("[1,2,3,5,6]", list.toString()); + } + + @Test + public void testRemoveRange() { + { + LinkedList linkedList = new LinkedList(); + + linkedList.add(11); + linkedList.add(12); + linkedList.add(13); + linkedList.add(14); + linkedList.add(16); + linkedList.add(16); + linkedList.add(19); + + linkedList.removeRange(10, 19); + Assert.assertEquals("[19]", linkedList.toString()); + } + + { + LinkedList linkedList = new LinkedList(); + + linkedList.add(11); + linkedList.add(12); + linkedList.add(13); + linkedList.add(14); + linkedList.add(16); + linkedList.add(16); + linkedList.add(19); + + linkedList.removeRange(10, 14); + Assert.assertEquals("[14,16,16,19]", linkedList.toString()); + } + } + + @Test + public void testIntersection() { + LinkedList list1 = new LinkedList(); + list1.add(1); + list1.add(6); + list1.add(7); + + LinkedList list2 = new LinkedList(); + list2.add(2); + list2.add(5); + list2.add(6); + + LinkedList newList = list1.intersection(list2); + Assert.assertEquals("[6]", newList.toString()); + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/api/ConnectionTest.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/api/ConnectionTest.java new file mode 100644 index 0000000000..5e4259bddf --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/api/ConnectionTest.java @@ -0,0 +1,42 @@ +package com.coderising.download.api; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.impl.ConnectionManagerImpl; + +public class ConnectionTest { + @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); + + // 测试不充分,没有断言内容是否正确 + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/core/FileDownloaderTest.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/core/FileDownloaderTest.java new file mode 100644 index 0000000000..2631a1f90b --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/core/FileDownloaderTest.java @@ -0,0 +1,56 @@ +package com.coderising.download.core; + +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://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + + String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + + FileDownloader downloader = new FileDownloader(url, "c:\\coderising\\tmp\\test.jpg"); + + 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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ConfigurationTest.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..b8ab6c04b9 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,46 @@ +package com.coderising.litestruts; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..4362ae0ac7 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,104 @@ +package com.coderising.litestruts; + +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/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/StrutsTest.java b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..5174fc47f1 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,37 @@ +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/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/resources/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/resources/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionManagerImpl.java b/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionManagerImpl.java deleted file mode 100644 index d50036b8c8..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.eulerlcs.jmr.multiDL.impl; - -import com.github.eulerlcs.jmr.multiDL.api.Connection; -import com.github.eulerlcs.jmr.multiDL.api.ConnectionException; -import com.github.eulerlcs.jmr.multiDL.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - - @Override - public Connection open(String url) throws ConnectionException { - - return null; - } -} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-61-collection/pom.xml similarity index 94% rename from group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/pom.xml rename to group09/41689722.eulerlcs/2.code/jmr-61-collection/pom.xml index 90b5cc3818..1da435d5b6 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/pom.xml +++ b/group09/41689722.eulerlcs/2.code/jmr-61-collection/pom.xml @@ -7,7 +7,7 @@ 0.0.1-SNAPSHOT ../jmr-02-parent/pom.xml - jmr-61-170226-collection + jmr-61-collection eulerlcs master java road collection diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/java/com/github/eulerlcs/jmr/collection/core/ArrayList.java b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/java/com/github/eulerlcs/jmr/algorithm/ArrayList.java similarity index 99% rename from group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/java/com/github/eulerlcs/jmr/collection/core/ArrayList.java rename to group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/java/com/github/eulerlcs/jmr/algorithm/ArrayList.java index 1c039b8c62..555f5ea954 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/java/com/github/eulerlcs/jmr/collection/core/ArrayList.java +++ b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/java/com/github/eulerlcs/jmr/algorithm/ArrayList.java @@ -1,7 +1,7 @@ /** * 90% or more copy from jdk */ -package com.github.eulerlcs.jmr.collection.core; +package com.github.eulerlcs.jmr.algorithm; import java.util.Arrays; import java.util.Collection; diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/resources/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/resources/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/resources/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/resources/log4j.xml b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/resources/log4j.xml similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/resources/log4j.xml rename to group09/41689722.eulerlcs/2.code/jmr-61-collection/src/main/resources/log4j.xml diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/test/java/com/github/eulerlcs/jmr/collection/core/TestArrayList.java b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/test/java/com/github/eulerlcs/jmr/algorithm/TestArrayList.java similarity index 86% rename from group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/test/java/com/github/eulerlcs/jmr/collection/core/TestArrayList.java rename to group09/41689722.eulerlcs/2.code/jmr-61-collection/src/test/java/com/github/eulerlcs/jmr/algorithm/TestArrayList.java index 96e1049d73..47ed2e0bef 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/test/java/com/github/eulerlcs/jmr/collection/core/TestArrayList.java +++ b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/test/java/com/github/eulerlcs/jmr/algorithm/TestArrayList.java @@ -1,4 +1,4 @@ -package com.github.eulerlcs.jmr.collection.core; +package com.github.eulerlcs.jmr.algorithm; import java.util.List; @@ -9,8 +9,6 @@ import org.junit.BeforeClass; import org.junit.Test; -import com.github.eulerlcs.jmr.collection.core.ArrayList; - public class TestArrayList { @BeforeClass diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/data/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-61-collection/src/test/resources/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/data/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-61-collection/src/test/resources/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/data/struts.xml b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/data/struts.xml similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/data/struts.xml rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/data/struts.xml diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/pom.xml similarity index 95% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/pom.xml index 6ce14ac574..353155e346 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml +++ b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/pom.xml @@ -7,7 +7,7 @@ 0.0.1-SNAPSHOT ../jmr-02-parent/pom.xml - jmr-61-170305-litestruts + jmr-62-litestruts eulerlcs master java road lite struts diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/test/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/.gitkeep similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/test/resources/.gitkeep rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/.gitkeep diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/algorithm/ArrayUtil.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/algorithm/ArrayUtil.java similarity index 99% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/algorithm/ArrayUtil.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/algorithm/ArrayUtil.java index 36894f6e5b..c9cc7522b5 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/algorithm/ArrayUtil.java +++ b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/algorithm/ArrayUtil.java @@ -1,7 +1,7 @@ /** * 问题点: 没写注释,代码比较难读。尤其 merge方法。 */ -package com.github.eulerlcs.jmr.litestruts.algorithm; +package com.github.eulerlcs.jmr.algorithm; import java.util.Arrays; diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LoginAction.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LoginAction.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LoginAction.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LoginAction.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LogoutAction.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LogoutAction.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LogoutAction.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LogoutAction.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/Struts.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/Struts.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/Struts.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/Struts.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/View.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/View.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/View.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/core/View.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsAction.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsAction.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsAction.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsAction.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionResult.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionResult.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionResult.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionResult.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionRulerSet.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionRulerSet.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionRulerSet.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionRulerSet.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsConfig.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsConfig.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsConfig.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsConfig.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsDigester.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsDigester.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsDigester.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsDigester.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/resources/log4j.xml b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/resources/log4j.xml similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/resources/log4j.xml rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/main/resources/log4j.xml diff --git a/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/util/ArrayUtilTest.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/com/github/eulerlcs/jmr/algorithm/ArrayUtilTest.java similarity index 97% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/util/ArrayUtilTest.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/com/github/eulerlcs/jmr/algorithm/ArrayUtilTest.java index 5e88599842..7242407f74 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/util/ArrayUtilTest.java +++ b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/com/github/eulerlcs/jmr/algorithm/ArrayUtilTest.java @@ -1,15 +1,13 @@ /** * 问题点: 没有全分支覆盖。只简单的测了关键或者关心的case */ -package com.github.eulerlcs.jmr.litestruts.util; +package com.github.eulerlcs.jmr.algorithm; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.github.eulerlcs.jmr.litestruts.algorithm.ArrayUtil; - public class ArrayUtilTest { @Test diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/core/StrutsTest.java b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/core/StrutsTest.java similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/core/StrutsTest.java rename to group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/core/StrutsTest.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/resources/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/data/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-63-download/data/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-63-download/pom.xml similarity index 95% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml rename to group09/41689722.eulerlcs/2.code/jmr-63-download/pom.xml index 8f300f8306..8656e91371 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/pom.xml @@ -7,7 +7,7 @@ 0.0.1-SNAPSHOT ../jmr-02-parent/pom.xml - jmr-61-170312-multiThreadDownload + jmr-63-download eulerlcs master java road - download file by multiple thread diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/Iterator.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/Iterator.java new file mode 100644 index 0000000000..78d537e842 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/Iterator.java @@ -0,0 +1,8 @@ +package com.github.eulerlcs.jmr.algorithm; + +public interface Iterator { + public boolean hasNext(); + + public Object next(); + +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/LinkedList.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/LinkedList.java new file mode 100644 index 0000000000..7f42cc502b --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/LinkedList.java @@ -0,0 +1,126 @@ +package com.github.eulerlcs.jmr.algorithm; + +public class LinkedList implements List { + + private Node head; + + 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 void addFirst(Object o) { + + } + + public void addLast(Object o) { + + } + + public Object removeFirst() { + return null; + } + + public Object removeLast() { + return null; + } + + public Iterator iterator() { + return null; + } + + private static class Node { + Object data; + Node next; + + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 + * + */ + public void removeFirstHalf() { + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + + } + + /** + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = + * 11->101->201->301->401->501->601->701 listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public static int[] getElements(LinkedList list) { + return null; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在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; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/List.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/List.java new file mode 100644 index 0000000000..d693a0895d --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/List.java @@ -0,0 +1,13 @@ +package com.github.eulerlcs.jmr.algorithm; + +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/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/Connection.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/Connection.java new file mode 100644 index 0000000000..30042c8db0 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/Connection.java @@ -0,0 +1,28 @@ +package com.github.eulerlcs.jmr.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/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionException.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionException.java new file mode 100644 index 0000000000..2ba4d3978c --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.github.eulerlcs.jmr.download.api; + +public class ConnectionException extends Exception { + private static final long serialVersionUID = 1L; +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionManager.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionManager.java new file mode 100644 index 0000000000..e2faed7df6 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionManager.java @@ -0,0 +1,11 @@ +package com.github.eulerlcs.jmr.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/DownloadListener.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/DownloadListener.java new file mode 100644 index 0000000000..80400ab21b --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.github.eulerlcs.jmr.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/DownloadThread.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/DownloadThread.java similarity index 72% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/DownloadThread.java rename to group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/DownloadThread.java index b3fb699944..179a037a92 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/DownloadThread.java +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/DownloadThread.java @@ -1,6 +1,6 @@ -package com.github.eulerlcs.jmr.multiDL; +package com.github.eulerlcs.jmr.download.core; -import com.github.eulerlcs.jmr.multiDL.api.Connection; +import com.github.eulerlcs.jmr.download.api.Connection; public class DownloadThread extends Thread { Connection conn; diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/FileDownloader.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/FileDownloader.java new file mode 100644 index 0000000000..fa3c193960 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/FileDownloader.java @@ -0,0 +1,64 @@ +package com.github.eulerlcs.jmr.download.core; + +import com.github.eulerlcs.jmr.download.api.Connection; +import com.github.eulerlcs.jmr.download.api.ConnectionException; +import com.github.eulerlcs.jmr.download.api.ConnectionManager; +import com.github.eulerlcs.jmr.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/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionImpl.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..72b679702b --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionImpl.java @@ -0,0 +1,25 @@ +package com.github.eulerlcs.jmr.download.impl; + +import java.io.IOException; + +import com.github.eulerlcs.jmr.download.api.Connection; + +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/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionManagerImpl.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..b24ae09984 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.github.eulerlcs.jmr.download.impl; + +import com.github.eulerlcs.jmr.download.api.Connection; +import com.github.eulerlcs.jmr.download.api.ConnectionException; +import com.github.eulerlcs.jmr.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return null; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/resources/log4j.xml b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/resources/log4j.xml similarity index 100% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/resources/log4j.xml rename to group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/resources/log4j.xml diff --git a/group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/java/com/github/eulerlcs/jmr/download/core/FileDownloaderTest.java b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/java/com/github/eulerlcs/jmr/download/core/FileDownloaderTest.java new file mode 100644 index 0000000000..531601606e --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/java/com/github/eulerlcs/jmr/download/core/FileDownloaderTest.java @@ -0,0 +1,53 @@ +package com.github.eulerlcs.jmr.download.core; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.eulerlcs.jmr.download.api.ConnectionManager; +import com.github.eulerlcs.jmr.download.api.DownloadListener; +import com.github.eulerlcs.jmr.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://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/group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/resources/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/data/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/data/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrame.java b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrame.java new file mode 100644 index 0000000000..25268be2dc --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrame.java @@ -0,0 +1,110 @@ +package com.github.eulerlcs.jmr.algorithm; + +/** + * 用双向链表实现LRU算法 + * + * @author liuxin, eulerlcs + */ +public class LRUPageFrame { + private static class Node { + Node prev; + Node next; + int pageNum; + } + + private int capacity; + private int length = 0; + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param pageNum + */ + public void access(int pageNum) { + Node node = findNode(pageNum); + + if (node != null) { + moveToFirst(node); + } else { + node = new Node(); + node.pageNum = pageNum; + addToFirst(node); + } + } + + private Node findNode(int pageNum) { + Node node = first; + + while (node != null) { + if (node.pageNum == pageNum) { + return node; + } else { + node = node.next; + } + } + + return null; + } + + private void moveToFirst(Node node) { + if (node == first) { + return; + } else if (node == last) { + last = node.prev; + } + + if (node.prev != null) { + node.prev.next = node.next; + } + if (node.next != null) { + node.next.prev = node.prev; + } + + first.prev = node; + node.prev = null; + node.next = first; + + first = node; + } + + private void addToFirst(Node node) { + if (first == null) { + first = node; + last = first; + } else { + first.prev = node; + node.next = first; + first = node; + } + + length++; + if (length > capacity) { + last.prev.next = null; + last = last.prev; + + length = capacity; + } + } + + @Override + 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/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileLoader.java b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6ef696c8b8 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileLoader.java @@ -0,0 +1,66 @@ +package com.github.eulerlcs.jmr.jvm.loader; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ClassFileLoader { + private final static Logger log = LoggerFactory.getLogger(ClassFileLoader.class); + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + File file = findClassFile(className); + if (file == null) { + return new byte[0]; + } + + byte[] ret = null; + byte[] bytes = new byte[(int) file.length()]; + try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) { + dis.readFully(bytes); + ret = bytes; + } catch (IOException e) { + log.error("ClassFileLoader read error!", e); + } + + return ret; + } + + private File findClassFile(String className) { + String sub = className.replace(".", File.separator) + ".class"; + for (String clzPath : clzPaths) { + File file = new File(clzPath, sub); + if (file.exists()) { + return file; + } + } + + return null; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + if (clzPaths.size() == 0) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + for (String clzPath : clzPaths) { + sb.append(";"); + sb.append(clzPath); + } + + String cat = sb.toString(); + return cat.length() > 0 ? cat.substring(1) : ""; + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrameTest.java b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrameTest.java new file mode 100644 index 0000000000..debc4d7eb6 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrameTest.java @@ -0,0 +1,27 @@ +package com.github.eulerlcs.jmr.algorithm; + +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/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileloaderTest.java b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..b039c5f259 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileloaderTest.java @@ -0,0 +1,53 @@ +package com.github.eulerlcs.jmr.jvm.loader; + +import java.io.File; + +import javax.xml.bind.DatatypeConverter; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + private static String userDir = System.getProperty("user.dir"); + private static String path1 = "C:\temp"; + private static String path2 = userDir + File.separator + "target" + File.separator + "test-classes"; + private static String className = EmployeeV1.class.getName(); + private ClassFileLoader loader = null; + + @Before + public void setUp() throws Exception { + loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + } + + @After + public void tearDown() throws Exception { + loader = null; + } + + @Test + public void testClassPath() { + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1 + ";" + path2, clzPath); + } + + @Test + public void testClassFileLength() { + byte[] byteCodes = loader.readBinaryCode(className); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1078, byteCodes.length); + + } + + @Test + public void testMagicNumber() { + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[] { byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3] }; + String acctualValue = DatatypeConverter.printHexBinary(codes); + + Assert.assertEquals("CAFEBABE", acctualValue); + } +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/EmployeeV1.java b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..070ad19083 --- /dev/null +++ b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.github.eulerlcs.jmr.jvm.loader; + +public class EmployeeV1 { + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + } +} \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/resources/.gitkeep b/group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/resources/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group09/41689722.eulerlcs/5.settingfile/eclipsev45.epf b/group09/41689722.eulerlcs/5.settingfile/eclipsev45.epf new file mode 100644 index 0000000000..ca88d61e06 --- /dev/null +++ b/group09/41689722.eulerlcs/5.settingfile/eclipsev45.epf @@ -0,0 +1,186 @@ +#Sat Mar 11 11:44:44 JST 2017 +\!/= +/configuration/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true +/configuration/org.eclipse.ui.ide/MAX_RECENT_WORKSPACES=10 +/configuration/org.eclipse.ui.ide/RECENT_WORKSPACES=E\:\\10.github.repo\\coding2017.eulerlcs\\group09\\41689722.eulerlcs\\2.code +/configuration/org.eclipse.ui.ide/RECENT_WORKSPACES_PROTOCOL=3 +/configuration/org.eclipse.ui.ide/SHOW_RECENT_WORKSPACES=false +/configuration/org.eclipse.ui.ide/SHOW_WORKSPACE_SELECTION_DIALOG=true +/instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true +/instance/org.eclipse.core.resources/encoding=UTF-8 +/instance/org.eclipse.core.resources/version=1 +/instance/org.eclipse.debug.core/prefWatchExpressions=\r\n\r\n +/instance/org.eclipse.debug.ui/org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=\r\n\r\n +/instance/org.eclipse.debug.ui/pref_state_memento.org.eclipse.debug.ui.DebugVieworg.eclipse.debug.ui.DebugView=\r\n +/instance/org.eclipse.debug.ui/pref_state_memento.org.eclipse.debug.ui.ExpressionView=\r\n\r\n\r\n +/instance/org.eclipse.debug.ui/pref_state_memento.org.eclipse.debug.ui.VariableView=\r\n +/instance/org.eclipse.debug.ui/preferredDetailPanes=DefaultDetailPane\:DefaultDetailPane| +/instance/org.eclipse.e4.ui.css.swt.theme/themeid=org.eclipse.e4.ui.css.theme.e4_default6.0,6.1,6.2,6.3,10.0 +/instance/org.eclipse.e4.ui.workbench.renderers.swt/enableMRU=true +/instance/org.eclipse.e4.ui.workbench.renderers.swt/themeEnabled=true +/instance/org.eclipse.egit.core/GitRepositoriesView.GitDirectories=E\:\\10.github.repo\\coding2017.eulerlcs\\.git; +/instance/org.eclipse.egit.core/GitRepositoriesView.GitDirectories.relative=E\:\\10.github.repo\\coding2017.eulerlcs\\.git; +/instance/org.eclipse.epp.logging.aeri.ide/resetSendMode=KEEP +/instance/org.eclipse.epp.logging.aeri.ide/resetSendModeOn=0 +/instance/org.eclipse.epp.logging.aeri.ide/sendMode=NOTIFY +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.compliance=1.8 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.source=1.8 +/instance/org.eclipse.jdt.launching/org.eclipse.jdt.launching.PREF_VM_XML=\r\n\r\n\r\n\r\n\r\n\r\n +/instance/org.eclipse.jdt.ui/content_assist_number_of_computers=24 +/instance/org.eclipse.jdt.ui/content_assist_proposals_background=255,255,255 +/instance/org.eclipse.jdt.ui/content_assist_proposals_foreground=0,0,0 +/instance/org.eclipse.jdt.ui/editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +/instance/org.eclipse.jdt.ui/fontPropagated=true +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.internal.ui.navigator.layout=2 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.internal.ui.navigator.librariesnode=true +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.editor.tab.width= +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles.version=12 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.javadoclocations.migrated=true +/instance/org.eclipse.jdt.ui/org.eclipse.jface.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.jdt.ui/proposalOrderMigrated=true +/instance/org.eclipse.jdt.ui/sourceHoverBackgroundColor=255,255,225 +/instance/org.eclipse.jdt.ui/sp_cleanup.add_default_serial_version_id=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_generated_serial_version_id=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_annotations=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_deprecated_annotations=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_methods=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_nls_tags=false +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_override_annotations=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_missing_override_annotations_interface_methods=true +/instance/org.eclipse.jdt.ui/sp_cleanup.add_serial_version_id=false +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_blocks=true +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_parentheses_in_expressions=false +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_this_for_non_static_field_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.always_use_this_for_non_static_method_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.convert_functional_interfaces=false +/instance/org.eclipse.jdt.ui/sp_cleanup.convert_to_enhanced_for_loop=false +/instance/org.eclipse.jdt.ui/sp_cleanup.correct_indentation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code=true +/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code_changes_only=false +/instance/org.eclipse.jdt.ui/sp_cleanup.insert_inferred_type_arguments=false +/instance/org.eclipse.jdt.ui/sp_cleanup.make_local_variable_final=true +/instance/org.eclipse.jdt.ui/sp_cleanup.make_parameters_final=false +/instance/org.eclipse.jdt.ui/sp_cleanup.make_private_fields_final=true +/instance/org.eclipse.jdt.ui/sp_cleanup.make_type_abstract_if_missing_method=false +/instance/org.eclipse.jdt.ui/sp_cleanup.make_variable_declarations_final=false +/instance/org.eclipse.jdt.ui/sp_cleanup.never_use_blocks=false +/instance/org.eclipse.jdt.ui/sp_cleanup.never_use_parentheses_in_expressions=true +/instance/org.eclipse.jdt.ui/sp_cleanup.on_save_use_additional_actions=true +/instance/org.eclipse.jdt.ui/sp_cleanup.organize_imports=true +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_private_constructors=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_redundant_type_arguments=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces_all=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unnecessary_casts=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unnecessary_nls_tags=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_imports=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_local_variables=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_fields=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_members=false +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_methods=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_unused_private_types=true +/instance/org.eclipse.jdt.ui/sp_cleanup.sort_members=false +/instance/org.eclipse.jdt.ui/sp_cleanup.sort_members_all=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_anonymous_class_creation=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_blocks=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_blocks_only_for_return_and_throw=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_lambda=true +/instance/org.eclipse.jdt.ui/sp_cleanup.use_parentheses_in_expressions=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_field_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_method_access=false +/instance/org.eclipse.jdt.ui/sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +/instance/org.eclipse.jdt.ui/spelling_locale_initialized=true +/instance/org.eclipse.jdt.ui/tabWidthPropagated=true +/instance/org.eclipse.jdt.ui/useAnnotationsPrefPage=true +/instance/org.eclipse.jdt.ui/useQuickDiffPrefPage=true +/instance/org.eclipse.jst.j2ee.webservice.ui/areThereWebServices=false +/instance/org.eclipse.m2e.discovery/org.eclipse.m2e.discovery.pref.projects= +/instance/org.eclipse.mylyn.context.core/mylyn.attention.migrated=true +/instance/org.eclipse.mylyn.monitor.ui/org.eclipse.mylyn.monitor.activity.tracking.enabled.checked=true +/instance/org.eclipse.mylyn.tasks.ui/migrated.task.repositories.secure.store=true +/instance/org.eclipse.mylyn.tasks.ui/org.eclipse.mylyn.tasks.ui.filters.nonmatching=true +/instance/org.eclipse.mylyn.tasks.ui/org.eclipse.mylyn.tasks.ui.filters.nonmatching.encouraged=true +/instance/org.eclipse.mylyn.tasks.ui/org.eclipse.mylyn.tasks.ui.welcome.message=true +/instance/org.eclipse.oomph.workingsets/working.set.group=\n\n +/instance/org.eclipse.rse.core/org.eclipse.rse.systemtype.local.systemType.defaultUserId=euler +/instance/org.eclipse.rse.ui/org.eclipse.rse.preferences.order.connections=euler-PC.Local +/instance/org.eclipse.team.ui/org.eclipse.team.ui.first_time=false +/instance/org.eclipse.ui.editors/overviewRuler_migration=migrated_3.1 +/instance/org.eclipse.ui.ide/PROBLEMS_FILTERS_MIGRATE=true +/instance/org.eclipse.ui.ide/platformState=1488095469945 +/instance/org.eclipse.ui.ide/quickStart=false +/instance/org.eclipse.ui.ide/tipsAndTricks=true +/instance/org.eclipse.ui.workbench//org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false +/instance/org.eclipse.ui.workbench//org.eclipse.ui.commands/state/org.eclipse.wst.xml.views.XPathView.processor.xpathprocessor/org.eclipse.ui.commands.radioState=xpath10 +/instance/org.eclipse.ui.workbench/ColorsAndFontsPreferencePage.expandedCategories=Torg.eclipse.ui.workbenchMisc\tTorg.eclipse.jdt.ui.presentation\tTorg.eclipse.wst.sse.ui +/instance/org.eclipse.ui.workbench/ColorsAndFontsPreferencePage.selectedElement=Forg.eclipse.jface.textfont +/instance/org.eclipse.ui.workbench/PLUGINS_NOT_ACTIVATED_ON_STARTUP=org.eclipse.m2e.discovery;org.eclipse.rse.ui; +/instance/org.eclipse.ui.workbench/REMOTE_COMMANDS_VIEW_FONT=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.compare.contentmergeviewer.TextMergeViewer=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.debug.ui.DetailPaneFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.debug.ui.MemoryViewTableFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.debug.ui.consoleFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.egit.ui.CommitMessageEditorFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.egit.ui.CommitMessageFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.egit.ui.DiffHeadlineFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.jdt.internal.ui.compare.JavaMergeViewer=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.jdt.internal.ui.compare.PropertiesFileMergeViewer=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.jdt.ui.PropertiesFileEditor.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.jdt.ui.editors.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.jface.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.mylyn.wikitext.ui.presentation.textFont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.pde.internal.ui.compare.ManifestContentMergeViewer=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.pde.internal.ui.compare.PluginContentMergeViewer=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.ui.commands=\r\n +/instance/org.eclipse.ui.workbench/org.eclipse.wst.jsdt.internal.ui.compare.JavaMergeViewer=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.wst.jsdt.ui.editors.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/org.eclipse.wst.sse.ui.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui.workbench/terminal.views.view.font.definition=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.ui/showIntro=false +/instance/org.eclipse.wst.jsdt.ui/fontPropagated=true +/instance/org.eclipse.wst.jsdt.ui/org.eclipse.jface.textfont=1|Consolas|12.0|0|WINDOWS|1|-16|0|0|0|400|0|0|0|0|3|2|1|49|Consolas; +/instance/org.eclipse.wst.jsdt.ui/org.eclipse.wst.jsdt.ui.editor.tab.width= +/instance/org.eclipse.wst.jsdt.ui/org.eclipse.wst.jsdt.ui.formatterprofiles.version=11 +/instance/org.eclipse.wst.jsdt.ui/org.eclipse.wst.jsdt.ui.javadoclocations.migrated=true +/instance/org.eclipse.wst.jsdt.ui/proposalOrderMigrated=true +/instance/org.eclipse.wst.jsdt.ui/tabWidthPropagated=true +/instance/org.eclipse.wst.jsdt.ui/useAnnotationsPrefPage=true +/instance/org.eclipse.wst.jsdt.ui/useQuickDiffPrefPage=true +@org.eclipse.core.net=1.3.0.v20160418-1534 +@org.eclipse.core.resources=3.11.1.v20161107-2032 +@org.eclipse.debug.core=3.10.100.v20160419-1720 +@org.eclipse.debug.ui=3.11.202.v20161114-0338 +@org.eclipse.e4.ui.css.swt.theme=0.10.100.v20160523-0836 +@org.eclipse.e4.ui.workbench.renderers.swt=0.14.0.v20160525-0940 +@org.eclipse.egit.core=4.4.1.201607150455-r +@org.eclipse.epp.logging.aeri.ide=2.0.3.v20161205-0933 +@org.eclipse.jdt.core=3.12.2.v20161117-1814 +@org.eclipse.jdt.launching=3.8.101.v20161111-2014 +@org.eclipse.jdt.ui=3.12.2.v20160929-0804 +@org.eclipse.jst.j2ee.webservice.ui=1.1.500.v201302011850 +@org.eclipse.m2e.discovery=1.7.0.20160603-1933 +@org.eclipse.mylyn.context.core=3.21.0.v20160701-1337 +@org.eclipse.mylyn.monitor.ui=3.21.0.v20160630-1702 +@org.eclipse.mylyn.tasks.ui=3.21.0.v20160913-2131 +@org.eclipse.oomph.workingsets=1.6.0.v20161019-0656 +@org.eclipse.rse.core=3.3.100.201603151753 +@org.eclipse.rse.ui=3.3.300.201610252046 +@org.eclipse.team.ui=3.8.0.v20160518-1906 +@org.eclipse.ui=3.108.1.v20160929-1045 +@org.eclipse.ui.editors=3.10.1.v20161106-1856 +@org.eclipse.ui.ide=3.12.2.v20161115-1450 +@org.eclipse.ui.workbench=3.108.2.v20161025-2029 +@org.eclipse.wst.jsdt.ui=2.0.0.v201608301904 +file_export_version=3.0 diff --git a/group09/610673813/src/coding/week02/array/ArrayUtil.java b/group09/610673813/src/coding/week02/array/ArrayUtil.java new file mode 100644 index 0000000000..ed443a2c22 --- /dev/null +++ b/group09/610673813/src/coding/week02/array/ArrayUtil.java @@ -0,0 +1,345 @@ +package coding.week02.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) + { + for(int i=0, j = origin.length-1; i array2[j]) + { + newArray[count++] = array2[j++]; + } + else if(array1[i] == array2[j]) + { + newArray[count++] = array2[j++]; + i++; + } + } + while(i==array1.length && j 1) + { + s = s + seperator; + for(int i=1; i= length - 1){ - endPos = length - 1; - } - new DownloadThread(barrier , conn, startPos, endPos , filePath).start(); - } + } - } catch (ConnectionException e) { - System.out.println(e.getMessage()); - } finally{ - if(conn != null){ - conn.close(); - } - } + public void oneThreadDownload() { + final CyclicBarrier barrier = new CyclicBarrier(1 ,new Runnable() { + @Override + public void run() { + getListener().notifyFinished(); + } + }); + try { + Thread thread = new DownloadThread("oneThread", conn,0,length, fileName, barrier); + thread.start(); + } finally { + if (conn != null) { + conn.close(); + } + } + } - } - - private String getFileType(String url) { - int index = url.lastIndexOf("."); - return url.substring(index + 1 , url.length()); - } + public void threadPoolDownload() throws ConnectionException { + final CyclicBarrier barrier = new CyclicBarrier(threadNum ,new Runnable() { + @Override + public void run() { + getListener().notifyFinished(); // 栅栏 + } + }); + ExecutorService threadPool = Executors.newCachedThreadPool(); + int len = conn.getContentLength(); + for(int i = 0; i< threadNum; i++) + { + int start=i*len/ threadNum; + int end = (i+1)*len/ threadNum -1; + conn = cm.open(this.url); + if(i== threadNum -1) + { + end =len; + } + Thread thread = new DownloadThread("thread"+i, conn, start, end, fileName, barrier); + threadPool.execute(thread); + } + if (conn != null) { + conn.close(); + } + } public void setListener(DownloadListener listener) { this.listener = listener; } - - public void setConnectionManager(ConnectionManager ucm){ this.cm = ucm; @@ -108,4 +115,4 @@ public DownloadListener getListener(){ return this.listener; } -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/download/FileDownloaderTest.java b/group09/790466157/src/com/coderising/download/FileDownloaderTest.java index a79d23d9c5..66d6455036 100644 --- a/group09/790466157/src/com/coderising/download/FileDownloaderTest.java +++ b/group09/790466157/src/com/coderising/download/FileDownloaderTest.java @@ -10,6 +10,7 @@ public class FileDownloaderTest { boolean downloadFinished = false; + private double time = 0; @Before public void setUp() throws Exception { } @@ -21,39 +22,34 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1488796402240&di=8ca9322617d5338cad61232a06f6ed7a&imgtype=0&src=http%3A%2F%2Fjiangsu.china.com.cn%2Fuploadfile%2F2017%2F0212%2F1486868426284307.jpg"; - - FileDownloader downloader = new FileDownloader(url); + String url = "http://inews.gtimg.com/newsapp_bt/0/1209438116/1000"; +// String url = "https://www.baidu.com/img/bd_logo.png"; + FileDownloader downloader = new FileDownloader(url, "test.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); + System.out.println("还没有下载完成,休眠0.01秒"); + time += 0.01; + //休眠0.01秒 + Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } - System.out.println("������ɣ�"); - - + System.out.println("下载完成!耗时"+time+"秒"); } - -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/download/api/Connection.java b/group09/790466157/src/com/coderising/download/api/Connection.java index fe772d969c..d370d27c68 100644 --- a/group09/790466157/src/com/coderising/download/api/Connection.java +++ b/group09/790466157/src/com/coderising/download/api/Connection.java @@ -4,23 +4,21 @@ public interface Connection { /** - * ʼͽλã ȡݣ ֵֽ - * @param startPos ʼλã 0ʼ - * @param endPos λ + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 * @return */ - public byte[] read(int startPos,int endPos) throws IOException; + byte[] read(int startPos, int endPos) throws IOException; + /** - * õݵij + * 得到数据内容的长度 * @return */ - public int getContentLength(); + int getContentLength(); /** - * ر + * 关闭连接 */ - public void close(); - public Connection open(Object url); + void close(); } - - diff --git a/group09/790466157/src/com/coderising/download/api/ConnectionException.java b/group09/790466157/src/com/coderising/download/api/ConnectionException.java index 132bf8fbdd..1551a80b3d 100644 --- a/group09/790466157/src/com/coderising/download/api/ConnectionException.java +++ b/group09/790466157/src/com/coderising/download/api/ConnectionException.java @@ -1,5 +1,5 @@ package com.coderising.download.api; public class ConnectionException extends Exception { - -} \ No newline at end of file + +} diff --git a/group09/790466157/src/com/coderising/download/api/ConnectionManager.java b/group09/790466157/src/com/coderising/download/api/ConnectionManager.java index e6a9811662..e3759c46ce 100644 --- a/group09/790466157/src/com/coderising/download/api/ConnectionManager.java +++ b/group09/790466157/src/com/coderising/download/api/ConnectionManager.java @@ -1,10 +1,13 @@ package com.coderising.download.api; +import java.io.IOException; +import java.net.ProtocolException; + public interface ConnectionManager { /** - * һurl , һ + * 给定一个url , 打开一个连接 * @param url * @return */ - public Connection open(String url) throws ConnectionException; -} \ No newline at end of file + Connection open(String url) throws ConnectionException; +} diff --git a/group09/790466157/src/com/coderising/download/api/DownloadListener.java b/group09/790466157/src/com/coderising/download/api/DownloadListener.java index 64ac13231b..de81b7607d 100644 --- a/group09/790466157/src/com/coderising/download/api/DownloadListener.java +++ b/group09/790466157/src/com/coderising/download/api/DownloadListener.java @@ -1,5 +1,5 @@ package com.coderising.download.api; public interface DownloadListener { - public void notifyFinished(); -} \ No newline at end of file + void notifyFinished(); +} diff --git a/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java b/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java index a0bea92f06..ba27ce6c9a 100644 --- a/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java +++ b/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java @@ -1,51 +1,64 @@ package com.coderising.download.impl; - +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Arrays; - - -import org.omg.CORBA.portable.InputStream; - +import com.basic.ArrayList; import com.coderising.download.api.Connection; +public class ConnectionImpl implements Connection{ + private HttpURLConnection downLoadConn; + private HttpURLConnection getLengthConn; -import java.net.URLConnection; + public ConnectionImpl(URL urlObject) { + HttpURLConnection conn = null; + try { + downLoadConn = (HttpURLConnection) urlObject.openConnection(); + downLoadConn.setRequestMethod("GET"); -import com.coderising.download.api.Connection; + getLengthConn = (HttpURLConnection) urlObject.openConnection(); + getLengthConn.setRequestMethod("GET"); + } catch (IOException e) { + e.printStackTrace(); + } + + } -public class ConnectionImpl implements Connection{ - -private URLConnection connection; - @Override public byte[] read(int startPos, int endPos) throws IOException { -// connection.setAllowUserInteraction(true); -// connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); - InputStream inputstream = (InputStream) connection.getInputStream(); - byte[] buffer = new byte[endPos - startPos + 1]; - inputstream.skip(startPos); - inputstream.read(buffer); - inputstream.close(); - return buffer; - } + downLoadConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream in = downLoadConn.getInputStream(); + byte[] buf = new byte[endPos-startPos+1]; + byte[] tempBuf = new byte[1024]; + BufferedInputStream bis = new BufferedInputStream(in); + int len = 0; + int totalLen = 0; + while((len=bis.read(tempBuf,0,tempBuf.length))!=-1){ + System.arraycopy(tempBuf, 0, buf, totalLen, len); + totalLen += len; + } + String desc = " bytes=" + startPos + "-" + endPos + " "; + System.out.println(Thread.currentThread().getName()+desc+totalLen); + in.close(); + bis.close(); + return Arrays.copyOf(buf, totalLen); + } @Override - public int getContentLength(){ - return connection.getContentLength(); + public int getContentLength() { + int len = getLengthConn.getContentLength(); + return len; } @Override public void close() { + downLoadConn.disconnect(); + getLengthConn.disconnect(); } - public void setConnection(URLConnection connection) { - this.connection = connection; - } - - @Override - public Connection open(Object url) { - // TODO Auto-generated method stub - return null; - } -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java index 99bdec847f..b66bb996be 100644 --- a/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java +++ b/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -1,35 +1,23 @@ package com.coderising.download.impl; - - - -import java.io.ByteArrayOutputStream; -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.impl.ConnectionImpl; import com.coderising.download.api.ConnectionException; import com.coderising.download.api.ConnectionManager; +import java.io.IOException; +import java.net.URL; + public class ConnectionManagerImpl implements ConnectionManager { @Override public Connection open(String url) throws ConnectionException { - URL urlObj ; - ConnectionImpl connection = null; - try { - urlObj = new URL(url); - connection = new ConnectionImpl(); - } catch (MalformedURLException e) { - throw new ConnectionException(); - } - return connection; + URL urlObject; + try { + urlObject = new URL(url); + return new ConnectionImpl(urlObject); + } catch (IOException e) { + e.printStackTrace(); + throw new ConnectionException(); + } } -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/linkedlist/Iterator.java b/group09/790466157/src/com/coderising/linkedlist/Iterator.java new file mode 100644 index 0000000000..b09016ee94 --- /dev/null +++ b/group09/790466157/src/com/coderising/linkedlist/Iterator.java @@ -0,0 +1,7 @@ +package com.coderising.linkedlist; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group09/790466157/src/com/coderising/linkedlist/LinkedList.java b/group09/790466157/src/com/coderising/linkedlist/LinkedList.java new file mode 100644 index 0000000000..7530d105e9 --- /dev/null +++ b/group09/790466157/src/com/coderising/linkedlist/LinkedList.java @@ -0,0 +1,263 @@ +package com.coderising.linkedlist; + +public class LinkedList implements List { + + private Node head; + private int size = 0; + + public void add(Object o){ + if(head == null){ + head = new Node(o); + }else{ + Node pos = head; + while(pos.next != null){ + pos = pos.next; + } + pos.next = new Node(o); + } + size++; + } + + public void add(int index , Object o){ + checkIndex(index); + if(index == 0) { + Node node = new Node(o); + node.next = head; + head = node; + } + else{ + Node pos = head; + for(int i = 0;i < index-1;i++){ + pos = pos.next; + } + Node node = new Node(o); + node.next = pos.next; + pos.next = node; + } + size++; + } + + private void checkIndex(int index) { + if(index < 0 || index >size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size); + } + + public Object get(int index){ + checkIndexPosition(index); + Node pos = head; + for(int i = 0;i < index;i++){ + pos = pos.next; + } + return pos.data; + } + + public Object remove(int index){ + checkIndexPosition(index); + Node element = head; + if(index == 0){ + head = head.next; + }else{ + Node pos = head; + for(int i = 0;i < index - 1;i++){ + pos = pos.next; + } + element = pos.next; + pos.next = pos.next.next; + } + size--; + return element.data; + } + + private void checkIndexPosition(int index) { + if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size); + } + + + public int size(){ + return size; + } + + public void addFirst(Object o){ + add(0,o); + } + + public void addLast(Object o){ + add(size,o); + } + + public Object removeFirst(){ + return remove(0); + } + + public Object removeLast(){ + return remove(size-1); + } + + public Iterator iterator(){ + return new LinkedListIterator(); + } + + class LinkedListIterator implements Iterator{ + + private Node node = head; + private int pos = 0; + @Override + public boolean hasNext() { + return pos < size; + } + + @Override + public Object next() { + pos++; + if(pos != 1){ + node = node.next; + } + return node.data; + } + } + + private static class Node{ + Object data; + Node next; + public Node(Object data){ + this.data = data; + next = null; + } + } + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(size == 0) return; + + for(int i=1;i5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(size == 0) return; + + int removeNum = size/2; + for(int i=0;i size || i<0 || i>=size) return; + + for(int k=i;k<(length+i);k++){ + remove(i); + } + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list == null) return new int[0]; + + int[] targetList = new int[list.size]; + for(int i=0;i min && (int)get(i) < max){ + remove(i--); + } + } + */ + + //遍历到最小值和最大值处并记录位置,最后调用remove(int i,int length)进行范围内的删除。 + int minPos = 0; + int maxPos = 0; + boolean exec = true; + for(int i=0;i min) { + minPos = i; + exec = false; + } else if((int)get(i) >max){ + maxPos = i; + break; + } + } + remove(minPos, maxPos - minPos); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList newList = new LinkedList(); + for(int i=0;i 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/group09/790466157/src/com/coderising/litestruts/ConfigurationException.java b/group09/790466157/src/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..97e286827f --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +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/group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java b/group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..734649f37a --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.coderising.litestruts; + +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/group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java b/group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..0bd53fea93 --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.coderising.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; + +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/group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java b/group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..cbe732d83f --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +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/group09/790466157/src/com/coderising/litestruts/SAX.java b/group09/790466157/src/com/coderising/litestruts/SAX.java deleted file mode 100644 index ab3f0c1044..0000000000 --- a/group09/790466157/src/com/coderising/litestruts/SAX.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.coderising.litestruts; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.Attributes; -public class SAX extends DefaultHandler { - //ĵʼ¼ - public void startDocument() { - System.out.println("ĵʼ "); - } - //ĵ¼ - public void endDocument() { - System.out.println("ĵ"); - } - //Ԫؿʼ¼ - public void startElement(String uri, String localName, String qname, Attributes attr) - { System.out.println("Ԫؿʼ: : " + localName + " ޶: " + qname + " ռURI: "+uri); - int attrCount = attr.getLength(); - if(attrCount>0) { - System.out.println(":"); - for(int i = 0 ; i parameters) { - /* - - 0. ȡļstruts.xml + /* + + 0. 读取配置文件struts.xml - 1. actionNameҵӦclass LoginAction, ͨʵ - parametersеݣösetter parametersе + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , "password"="1234") , - ǾӦõ setNamesetPassword + 那就应该调用 setName和setPassword方法 - 2. ͨöexectue ÷ֵ"success" + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" - 3. ͨҵgetter getMessage, - ͨã ֵγһHashMap , {"message": "¼ɹ"} , - ŵViewparameters + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters - 4. struts.xmlе ,Լexecuteķֵ ȷһjsp - ŵViewjspֶС + 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/group10/205301442/src/api/Connection.java b/group10/205301442/src/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group10/205301442/src/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/group10/205301442/src/api/ConnectionException.java b/group10/205301442/src/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group10/205301442/src/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group10/205301442/src/api/ConnectionManager.java b/group10/205301442/src/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group10/205301442/src/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/group10/205301442/src/api/DownloadListener.java b/group10/205301442/src/api/DownloadListener.java new file mode 100644 index 0000000000..41c4907246 --- /dev/null +++ b/group10/205301442/src/api/DownloadListener.java @@ -0,0 +1,6 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(boolean isFinish); + public boolean getIsFinished(); +} diff --git a/group10/205301442/src/com/coding/week1/LinkedList1.java b/group10/205301442/src/com/coding/week1/LinkedList1.java new file mode 100644 index 0000000000..9583a6505c --- /dev/null +++ b/group10/205301442/src/com/coding/week1/LinkedList1.java @@ -0,0 +1,280 @@ +package com.coding.week1; +import java.util.List; +import java.util.ArrayList; + +public class LinkedList1 { + private Node head; + private int size; + public void add(Object o){ + Node node = new Node(o,null); + node(size-1).next = node; + size++; + } + public void add(int index , Object o){ + if(index<0){ + return; + } + Node node = new Node(o,null); + if(index==0){ + head=node; + node.next = node(0); + }else{ + node(index-1).next = node; + node.next = node(index+1); + } + size++; + } + public Object get(int index){ + if(index<0){ + return null; + } + return node(index); + } + public Object remove(int index){ + if(index<0){ + return null; + } + Object o =node(index).data; + node(index-1).next = node(index+1); + size--; + return o; + } + + public int size(){ + return -1; + } + + public void addFirst(Object o){ + Node n = new Node(o,null); + head = n; + if(size>0){ + n.next = node(0); + } + size++; + + } + public void addLast(Object o){ + Node n = new Node(o,null); + if(size>0){ + node(size-1).next = n; + }else{ + head = n; + } + size++; + + } + public Object removeFirst(){ + return null; + } + public Object removeLast(){ + return null; + } + public Iterator iterator(){ + return new Ito(); + } + public class Ito implements Iterator{ + int cursor; + @Override + public boolean hasNext() { + if(cursor!=size){ + return true; + } + return false; + } + + @Override + public Object next() { + if(cursor>=size-1){ + return null; + } + Object o=node(cursor).data; + cursor++; + return o; + + } + + } + + + private static class Node{ + Object data; + Node next; + public Node(Object data,Node next){ + this.data = data; + this.next = next; + } + + + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Node x = node(size-1); + head = x; + for(int i=size-2;i>=0;i--){ + x.next = node(i); + x = node(i); + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int newSize = size/2+size%2; + head = node(newSize-1); + size = newSize; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + + if(i==0){ + head = node(length); + } + node(i-1).next = node(i+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){ + int[] temp = new int[size]; + for(int i=0;i-1){ + temp[0]=Integer.parseInt(o); + j++; + } + } + + } + return null; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + int[] temp = new int[size]; + int newSize = 0; + for(int i=0;i lists = new ArrayList(); + while(true){ + if((int)n.data>min&&(int)n.data0){ + if(nowLen+m>len){ + System.arraycopy(temp, 0, bt, nowLen, len-nowLen); + break; + } + System.arraycopy(temp, 0, bt, nowLen, m); + nowLen += m; + + } + return bt; + } + + @Override + public int getContentLength() { + if(is==null){ + return 0; + } + try { + int length=conn.getContentLength(); + return length; + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return 0; + } + + @Override + public void close() { + if(is!=null){ + try { + is.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + +} diff --git a/group10/205301442/src/download/impl/ConnectionManagerImpl.java b/group10/205301442/src/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..34e02aad97 --- /dev/null +++ b/group10/205301442/src/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,34 @@ +package com.coderising.download.impl; + +import java.io.DataInputStream; +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 { + + //在connection里实现连接,不再这儿,这里只是返回 + @Override + public Connection open(String url) throws ConnectionException { + try { + + + URL uri = new URL(url); + HttpURLConnection conn = (HttpURLConnection) uri.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5*1000); + Connection connImpl = new ConnectionImpl(conn); + return connImpl; + } catch (IOException e) { + // TODO Auto-generated catch block + + } + return null; + } + +} diff --git a/group10/205301442/src/download/impl/DoloadListenerImpl.java b/group10/205301442/src/download/impl/DoloadListenerImpl.java new file mode 100644 index 0000000000..d448b817c3 --- /dev/null +++ b/group10/205301442/src/download/impl/DoloadListenerImpl.java @@ -0,0 +1,16 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.DownloadListener; + +public class DoloadListenerImpl implements DownloadListener{ + boolean isFinish = false; + @Override + public void notifyFinished(boolean isfinish) { + // TODO Auto-generated method stub + this.isFinish = isfinish; + } + public boolean getIsFinished(){ + return isFinish; + } + +} diff --git a/group10/205301442/src/impl/ConnectionImpl.java b/group10/205301442/src/impl/ConnectionImpl.java new file mode 100644 index 0000000000..612ef940c9 --- /dev/null +++ b/group10/205301442/src/impl/ConnectionImpl.java @@ -0,0 +1,76 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + + private HttpURLConnection conn; + private InputStream is; + public ConnectionImpl(HttpURLConnection conn) { + try { + this.conn = conn; + is = conn.getInputStream(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + if(is==null){ + return null; + } + + is.skip(startPos); + int len = endPos-startPos; + byte[] bt = new byte[len]; + byte[] temp = new byte[1024]; + int m=0; + int nowLen=0; + while((m=is.read(temp))>0){ + if(nowLen+m>len){ + System.arraycopy(temp, 0, bt, nowLen, len-nowLen); + break; + } + System.arraycopy(temp, 0, bt, nowLen, m); + nowLen += m; + + } + return bt; + } + + @Override + public int getContentLength() { + if(is==null){ + return 0; + } + try { + int length=conn.getContentLength(); + return length; + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return 0; + } + + @Override + public void close() { + if(is!=null){ + try { + is.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + +} diff --git a/group10/205301442/src/impl/ConnectionManagerImpl.java b/group10/205301442/src/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..34e02aad97 --- /dev/null +++ b/group10/205301442/src/impl/ConnectionManagerImpl.java @@ -0,0 +1,34 @@ +package com.coderising.download.impl; + +import java.io.DataInputStream; +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 { + + //在connection里实现连接,不再这儿,这里只是返回 + @Override + public Connection open(String url) throws ConnectionException { + try { + + + URL uri = new URL(url); + HttpURLConnection conn = (HttpURLConnection) uri.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5*1000); + Connection connImpl = new ConnectionImpl(conn); + return connImpl; + } catch (IOException e) { + // TODO Auto-generated catch block + + } + return null; + } + +} diff --git a/group10/205301442/src/impl/DoloadListenerImpl.java b/group10/205301442/src/impl/DoloadListenerImpl.java new file mode 100644 index 0000000000..d448b817c3 --- /dev/null +++ b/group10/205301442/src/impl/DoloadListenerImpl.java @@ -0,0 +1,16 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.DownloadListener; + +public class DoloadListenerImpl implements DownloadListener{ + boolean isFinish = false; + @Override + public void notifyFinished(boolean isfinish) { + // TODO Auto-generated method stub + this.isFinish = isfinish; + } + public boolean getIsFinished(){ + return isFinish; + } + +} diff --git a/group10/904627477/src/com/coding/basic/LRUPageFrame.java b/group10/904627477/src/com/coding/basic/LRUPageFrame.java new file mode 100644 index 0000000000..d094f257e1 --- /dev/null +++ b/group10/904627477/src/com/coding/basic/LRUPageFrame.java @@ -0,0 +1,135 @@ +package com.coding.basic; + +/** + * 用双向链表实现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) { + Node node = findPageNumNode(pageNum); + if(node==null){ + if(size()>=capacity){ + removeLast(); + } + push(pageNum); + }else{ + moveToFirst(node); + } + } + + public Node findPageNumNode(int pageNum) { + Node node = first; + while(node!=null){ + if(node.pageNum==pageNum){ + break; + }else{ + node = node.next; + } + } + return node; + } + + public void moveToFirst(Node node) { + if(first==null||node==null||first.pageNum==node.pageNum){ + return; + } + if(node.pageNum == last.pageNum){ + node.prev.next = null; + last = node.prev; + }else{ + Node tPrev = node.prev; + Node tNext = node.next; + tPrev.next = tNext; + tNext.prev = tPrev; + } + node.prev = null; + node.next = first; + first = node; + } + + public void push(int pageNum) { + if(size()==0){ + first = new Node(); + first.pageNum = pageNum; + last = first; + return ; + } + Node node; + node = new Node(); + node.pageNum = pageNum; + node.next = first; + first.prev = node; + first = node; + } + + public void removeLast() { + if(last==null){ + return ; + } + if(size()==1){ + first = null; + last = null; + return ; + } + Node temp = last.prev; + last.prev = null; + last = temp; + last.next = null; + } + + public int size() { + int size = 0; + Node temp = first; + while (temp!=null) { + size++; + temp = temp.next; + } + return 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/group10/904627477/src/com/coding/download/CreateThread.java b/group10/904627477/src/com/coding/download/CreateThread.java index d9a22edbbd..3ac8662f90 100644 --- a/group10/904627477/src/com/coding/download/CreateThread.java +++ b/group10/904627477/src/com/coding/download/CreateThread.java @@ -1,32 +1,32 @@ -package com.coding.download; - - -import com.coding.download.api.Resource; - -public class CreateThread extends Thread { - - private Resource resource; - private int length; - - public CreateThread(Resource resource,int length){ - this.resource = resource; - this.length = length; - } - - @Override - public void run() { - int startPos = 0; - while(true){ - //System.out.println(startPos); - if(startPos>=length){ - resource.setFlag(true); - break; - }else{ - startPos = resource.increace(); - } - } - } - - - -} +package com.coding.download; + + +import com.coding.download.api.Resource; + +public class CreateThread extends Thread { + + private Resource resource; + private int length; + + public CreateThread(Resource resource,int length){ + this.resource = resource; + this.length = length; + } + + @Override + public void run() { + int startPos = 0; + while(true){ + //System.out.println(startPos); + if(startPos>=length){ + resource.setFlag(true); + break; + }else{ + startPos = resource.increace(); + } + } + } + + + +} diff --git a/group10/904627477/src/com/coding/download/DownloadThread.java b/group10/904627477/src/com/coding/download/DownloadThread.java index 7e98539050..98a811e9ac 100644 --- a/group10/904627477/src/com/coding/download/DownloadThread.java +++ b/group10/904627477/src/com/coding/download/DownloadThread.java @@ -2,7 +2,8 @@ import java.io.File; import java.io.IOException; -import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; import com.coding.download.api.Connection; import com.coding.util.IOUtils; @@ -13,9 +14,17 @@ public class DownloadThread extends Thread { int startPos; int endPos; private File file; + private CyclicBarrier barrier; + public DownloadThread(Connection conn, int startPos, int endPos,File file,CyclicBarrier barrier) { + this.barrier = barrier; + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.file = file; + } + public DownloadThread(Connection conn, int startPos, int endPos,File file) { - this.conn = conn; this.startPos = startPos; this.endPos = endPos; @@ -29,8 +38,15 @@ public void run() { if(buff!=null&&buff.length!=0){ IOUtils.writeFile(file, startPos, buff); } + if(barrier!=null){ //修改后代码 + barrier.await(); + } } catch (IOException e) { e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); } } } diff --git a/group10/904627477/src/com/coding/download/FileDownloader.java b/group10/904627477/src/com/coding/download/FileDownloader.java index 146491f2db..19a0f081b2 100644 --- a/group10/904627477/src/com/coding/download/FileDownloader.java +++ b/group10/904627477/src/com/coding/download/FileDownloader.java @@ -1,17 +1,12 @@ package com.coding.download; import java.io.File; -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 com.coding.download.api.Connection; import com.coding.download.api.ConnectionException; import com.coding.download.api.ConnectionManager; import com.coding.download.api.DownloadListener; -import com.coding.download.api.Resource; import com.coding.util.IOUtils; @@ -26,6 +21,7 @@ public class FileDownloader { ConnectionManager cm; private static String localFile = "c:/test/test.jpg"; + private final static int MAX_THREAD_NUM = 3; public FileDownloader(String _url) { @@ -47,14 +43,12 @@ public void execute(){ // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 - /**/ + /* my try { Connection conn = cm.open(url); int length = conn.getContentLength(); File file = new File(localFile); - if(!file.exists()){ - IOUtils.createFile(length, localFile); - } + IOUtils.createFile(length, localFile); Resource res = new Resource(url,file); Thread c = new CreateThread(res,length); Thread r = new RemoveThread(res,listener); @@ -63,26 +57,30 @@ public void execute(){ } catch (ConnectionException e) { e.printStackTrace(); } - /*Connection conn = null; + */ try { - conn = cm.open(this.url); - int length = conn.getContentLength(); + CyclicBarrier barrier = new CyclicBarrier(MAX_THREAD_NUM, new Runnable() { + @Override + public void run() { + listener.notifyFinished(); + } + }); + Connection conn = cm.open(url); + int length = conn.getContentLength(); + IOUtils.createFile(length, localFile); File file = new File(localFile); - if(!file.exists()){ - IOUtils.createFile(length, localFile); + int size = length/MAX_THREAD_NUM; + int last = length%MAX_THREAD_NUM; + for(int i=0;i results = new HashMap(); + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getClazz() { + return clazz; + } + public void setClazz(String clazz) { + this.clazz = clazz; + } + public String getMethod() { + return method; + } + public void setMethod(String method) { + this.method = method; + } + public Map getResults() { + return results; + } + public void setResults(Map results) { + this.results = results; + } + public Action() { + super(); + // TODO Auto-generated constructor stub + } + public Action(String name, String clazz, String method) { + super(); + this.name = name; + this.clazz = clazz; + this.method = method; + this.results = new HashMap(); + } + + +} diff --git a/group10/904627477/src/com/coding/litestruts/Result.java b/group10/904627477/src/com/coding/litestruts/Result.java new file mode 100644 index 0000000000..c9492040cd --- /dev/null +++ b/group10/904627477/src/com/coding/litestruts/Result.java @@ -0,0 +1,42 @@ +package com.coding.litestruts; + +public class Result { + + public final static String DEFAULT_NAME="success"; + + private String name; + private String type; + private String jspPath; + 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 String getJspPath() { + return jspPath; + } + public void setJspPath(String jspPath) { + this.jspPath = jspPath; + } + public Result(String name, String type, String jspPath) { + super(); + this.name = name; + this.type = type; + this.jspPath = jspPath; + } + public Result() { + super(); + // TODO Auto-generated constructor stub + } + + + + +} diff --git a/group10/904627477/src/com/coding/litestruts/Struts.java b/group10/904627477/src/com/coding/litestruts/Struts.java index eb68fa9441..8c359cf094 100644 --- a/group10/904627477/src/com/coding/litestruts/Struts.java +++ b/group10/904627477/src/com/coding/litestruts/Struts.java @@ -1,11 +1,6 @@ package com.coding.litestruts; -import java.util.List; import java.util.Map; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.Element; -import org.dom4j.io.SAXReader; @@ -37,21 +32,21 @@ public static View runAction(String actionName, Map parameters) { } View view = new View(); String path = getStrutsXMLPath(); - Element actionEle = getActionElement(path, actionName); + Action actionEle = StrutsXMLParser.getStrutsXML(path).get(actionName); if(actionEle==null){ return null; } - String className = actionEle.attributeValue("class"); - Object action = ReflectUtil.getObject(className, parameters); - if(action==null){ - return null; - } - String methodName = actionEle.attributeValue("method"); - methodName = methodName==null?"execute":methodName; - Object reslut = ReflectUtil.exectue(action, methodName); - String jsp = getElementJsp(actionEle, reslut!=null?reslut.toString():null); - view.setJsp(jsp); - view.setParameters(ReflectUtil.getAttributes(action)); + Object action = ReflectUtil.getObject(actionEle.getClazz(), parameters); + if(action==null){ + return null; + } + Object reslut = ReflectUtil.exectue(action, actionEle.getMethod()); + if(reslut==null){ + return null; + } + Result resultEle = actionEle.getResults().get(reslut.toString()); + view.setJsp(resultEle.getJspPath()); + view.setParameters(ReflectUtil.getAttributes(action)); return view; } @@ -60,47 +55,6 @@ private static String getStrutsXMLPath(){ path = path.substring(1); return path; } - - @SuppressWarnings("unchecked") - public static Element getActionElement(String path,String actionName){ - if(path==null||actionName==null){ - return null; - } - Element actionEle = null; - try { - SAXReader read = new SAXReader(); - Document doc = read.read(path); - Element root = doc.getRootElement(); - List actions = root.elements("action"); - for (Element element : actions) { - String name = element.attributeValue("name"); - if(actionName.equals(name)){ - actionEle = element; - break; - } - } - } catch (SecurityException e) { - e.printStackTrace(); - } catch (DocumentException e) { - e.printStackTrace(); - } - return actionEle; - } - - @SuppressWarnings("unchecked") - public static String getElementJsp(Element actionEle, String reslut) { - String jsp = null; - if(reslut!=null){ - List results = actionEle.elements("result"); - for (Element reslutEle : results) { - String resName = reslutEle.attributeValue("name"); - resName = resName==null?"success":resName; - if(reslut.equals(resName)){ - jsp = reslutEle.getText().trim(); - } - } - } - return jsp; - } + } diff --git a/group10/904627477/src/com/coding/litestruts/StrutsXMLParser.java b/group10/904627477/src/com/coding/litestruts/StrutsXMLParser.java new file mode 100644 index 0000000000..033da7cc87 --- /dev/null +++ b/group10/904627477/src/com/coding/litestruts/StrutsXMLParser.java @@ -0,0 +1,68 @@ +package com.coding.litestruts; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +public class StrutsXMLParser { + + public static Map getStrutsXML(){ + String path = System.getProperty("user.dir"); + path = path + "/src/struts.xml"; + return getStrutsXML(path); + } + + public static Map getStrutsXML(String xmlPath){ + if(xmlPath==null){ + throw new IllegalArgumentException(); + } + Map actions = new HashMap(); + try { + SAXReader read = new SAXReader(); + Document doc = read.read(xmlPath); + Element root = doc.getRootElement(); + @SuppressWarnings("unchecked") + List eles = root.elements("action"); + for (Element element : eles) { + String name = element.attributeValue("name"); + actions.put(name, getAction(element)); + } + } catch (SecurityException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + return actions; + } + + private static Action getAction(Element element) { + String name = element.attributeValue("name"); + String clazz = element.attributeValue("class"); + String method = element.attributeValue("method"); + method = method==null?Action.DEFAULT_METHOD:method; + Action action = new Action(name, clazz, method); + @SuppressWarnings("unchecked") + List eles = element.elements("result"); + for (Element ele : eles) { + String resName = ele.attributeValue("name"); + resName = resName==null?Result.DEFAULT_NAME:resName; + action.getResults().put(resName, getResult(ele)); + } + return action; + } + + private static Result getResult(Element ele) { + String name = ele.attributeValue("name"); + name = name==null?Result.DEFAULT_NAME:name; + String type = ele.attributeValue("type"); + String jspPath = ele.getText().trim(); + Result result = new Result(name, type, jspPath); + return result; + } + +} diff --git a/group10/904627477/src/com/coding/test/ClassFileloaderTest.java b/group10/904627477/src/com/coding/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..5fff5e1711 --- /dev/null +++ b/group10/904627477/src/com/coding/test/ClassFileloaderTest.java @@ -0,0 +1,88 @@ +package com.coding.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.conding.jvm.loader.ClassFileLoader; + +public class ClassFileloaderTest { + + + static String path1 = "D:\\workspace\\MyGithub\\coding2017\\group10\\904627477\\target\\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.coding.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1040, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coding.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 clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className){ + String filePath = getFilePath(className); + if(filePath==null){ + return null; + } + byte[] result = IOUtils.readFile(filePath); + return result; + } + + public String getFilePath(String className) { + String filePath = null; + String relativePath = className.replace('.', '/')+".class"; + for (String str : clzPaths) { + String tempPath = str + "/" + relativePath; + File file = new File(tempPath); + if(file.exists()){ + filePath = tempPath; + break; + } + } + return filePath; + } + + public void addClassPath(String path) { + if(path==null||"".equals(path)){ + return; + } + if(clzPaths.indexOf(path)!=-1){ + return ; + } + clzPaths.add(path); + } + + public String getClassPath(){ + StringBuffer sb = new StringBuffer(); + for (String clzPath : clzPaths) { + sb.append(clzPath+";"); + } + return sb.length()==0?"":sb.substring(0, sb.length()-1); + } + +} diff --git a/group13/2729382520/L4/src/io/github/vxzh/jvm/loader/ClassFileLoader.java b/group13/2729382520/L4/src/io/github/vxzh/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..db6f3b81ef --- /dev/null +++ b/group13/2729382520/L4/src/io/github/vxzh/jvm/loader/ClassFileLoader.java @@ -0,0 +1,79 @@ +package io.github.vxzh.jvm.loader; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private static final int BUFFER_MAX_SIZE = 1024; + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + className = className.replaceAll("\\.", "/"); + File file = findFile(className); + if (file == null) { + return new byte[0]; + } + + FileInputStream fis = null; + ByteArrayOutputStream bos = null; + try { + fis = new FileInputStream(file); + bos = new ByteArrayOutputStream(); + byte buffer[] = new byte[BUFFER_MAX_SIZE]; + int len = -1; + while ((len = fis.read(buffer)) != -1) { + bos.write(buffer, 0, len); + } + return bos.toByteArray(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fis != null) + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + if (bos != null) + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return null; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + + StringBuilder builder = new StringBuilder(); + for (String path : clzPaths) { + builder.append(path).append(";"); + } + + return builder.toString().substring(0, builder.toString().length() - 1); + } + + private File findFile(String className) { + for (String path : clzPaths) { + String filePath = path + "/" + className + ".class"; + File file = new File(filePath); + if (file.exists()) { + return file; + } + } + return null; + } +} \ No newline at end of file diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java b/group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java similarity index 60% rename from group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java rename to group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java index 66855937f4..8f8607162f 100644 --- a/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java +++ b/group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java @@ -1,90 +1,82 @@ -package zavier.week04.coderising.jvm.test; - -import java.io.File; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import zavier.week04.coderising.jvm.loader.ClassFileLoader; - - - -public class ClassFileloaderTest { - - - static String path1 = new File(".", "bin").getAbsolutePath(); - static String path2 = "C:\\temp"; - - static String className = EmployeeV1.class.getName(); - - @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() throws ClassNotFoundException { - - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - - byte[] byteCodes = loader.readBinaryCode(className); - - // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1076, byteCodes.length); - - } - - @Test(expected = ClassNotFoundException.class) - public void testClassNotFindException() throws ClassNotFoundException { - ClassFileLoader loader = new ClassFileLoader(); - loader.readBinaryCode(className); - } - - - @Test - public void testMagicNumber() throws ClassNotFoundException { - ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path1); - 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 < codes.length; i++) { - byte b = codes[i]; - int value = b & 0xFF; - String strHex = Integer.toHexString(value); - if (strHex.length() < 2) { - strHex = "0" + strHex; - } - buffer.append(strHex); - } - return buffer.toString(); - } - -} +package io.github.vxzh.jvm.test; + +import io.github.vxzh.jvm.loader.ClassFileLoader; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + + static String path1 = "/Users/xuxiaoqing/Workspace/test"; + static String path2 = "/Users/xuxiaoqing/Documents/demo"; + + + @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 = "io.github.vxzh.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 = "io.github.vxzh.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 < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + +} \ No newline at end of file diff --git a/group13/2729382520/L4/src/io/github/vxzh/jvm/test/EmployeeV1.java b/group13/2729382520/L4/src/io/github/vxzh/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..d0507a84ac --- /dev/null +++ b/group13/2729382520/L4/src/io/github/vxzh/jvm/test/EmployeeV1.java @@ -0,0 +1,29 @@ +package io.github.vxzh.jvm.test; + +public class EmployeeV1 { + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + } +} \ No newline at end of file diff --git a/group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrame.java b/group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrame.java new file mode 100644 index 0000000000..f2858f5d69 --- /dev/null +++ b/group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrame.java @@ -0,0 +1,109 @@ +package io.github.vxzh.lru; + +/** + * 用双向链表实现LRU算法 + */ +public class LRUPageFrame { + + private static class Node { + Node prev; + Node next; + int pageNum; + + Node(Node prev, int pageNum, Node next) { + this.prev = prev; + this.pageNum = pageNum; + this.next = next; + } + } + + private int capacity; + private int size; + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + if (first != null && first.pageNum == pageNum) { + return; + } + + removeNode(pageNum); + if (size() + 1 > capacity) { + removeLast(); + } + addFirst(pageNum); + + } + + private int size() { + return size; + } + + private void addFirst(int pageNum) { + Node f = first; + Node newNode = new Node(null, pageNum, f); + if (f == null) + last = newNode; + else + f.prev = newNode; + first = newNode; + size++; + } + + private void removeLast() { + + Node l = last; + Node prev = l.prev; + prev.next = null; + l.prev = null; + last = prev; + size--; + } + + private void removeNode(int pageNum) { + Node node = first; + while (node != null) { + if (node.pageNum == pageNum) { + if (node == last) { + removeLast(); + } else { + final Node prev = node.prev; + final Node next = node.next; + prev.next = next; + next.prev = prev; + node.prev = null; + node.next = null; + size--; + } + break; + } else { + node = node.next; + } + } + } + + 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(); + } + +} \ No newline at end of file diff --git a/group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrameTest.java b/group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..584632554c --- /dev/null +++ b/group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrameTest.java @@ -0,0 +1,29 @@ +package io.github.vxzh.lru; + +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()); + } + +} \ No newline at end of file diff --git a/group13/2931408816/lesson4/build.gradle b/group13/2931408816/lesson4/build.gradle new file mode 100644 index 0000000000..f4062b8d33 --- /dev/null +++ b/group13/2931408816/lesson4/build.gradle @@ -0,0 +1,27 @@ +group 'cn.net.pikachu' +version '1.0-SNAPSHOT' + +buildscript { + ext.kotlin_version = '1.1.1' + + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" + testCompile group: 'junit', name: 'junit', version: '4.12' +} diff --git a/group13/2931408816/lesson4/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group13/2931408816/lesson4/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6e2869d8ec --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.loader; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + try { + String path = className.replaceAll("\\.","/"); + System.out.println(path); +// String base = Thread.currentThread().getContextClassLoader().getResource("/").getPath(); + String base = "D:\\src\\java\\study\\coding2017\\group13\\2931408816\\lesson4\\build\\classes\\main"; + System.out.println(base); + InputStream inputStream = new FileInputStream(base+"/"+path+".class"); + byte[] bytes = new byte[inputStream.available()]; + inputStream.read(bytes); + return bytes; + } catch (IOException e) { + e.printStackTrace(); + } + return null; + + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuilder builder = new StringBuilder(); + for (String s : + clzPaths) { + builder.append(s).append(";"); + } + builder.deleteCharAt(builder.length()-1); + return builder.toString(); +// return null; + } + + + + + +} diff --git a/group13/2931408816/lesson4/src/main/java/com/coderising/jvm/test/EmployeeV1.java b/group13/2931408816/lesson4/src/main/java/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..12e3d7efdd --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coderising/jvm/test/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.test; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/BinaryTreeNode.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/BinaryTreeNode.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/BinaryTreeNode.java rename to group13/2931408816/lesson4/src/main/java/com/coding/basic/BinaryTreeNode.java diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/Iterator.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/Iterator.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/Iterator.java rename to group13/2931408816/lesson4/src/main/java/com/coding/basic/Iterator.java diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/List.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/List.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/List.java rename to group13/2931408816/lesson4/src/main/java/com/coding/basic/List.java diff --git a/group13/2931408816/lesson4/src/main/java/com/coding/basic/Queue.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/Queue.java new file mode 100644 index 0000000000..36e516e266 --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/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/liuxin/data-structure/src/com/coding/basic/Stack.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/Stack.java similarity index 100% rename from liuxin/data-structure/src/com/coding/basic/Stack.java rename to group13/2931408816/lesson4/src/main/java/com/coding/basic/Stack.java diff --git a/group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayList.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayList.java new file mode 100644 index 0000000000..4576c016af --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayList.java @@ -0,0 +1,35 @@ +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +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/group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayUtil.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..45740e6d57 --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,96 @@ +package com.coding.basic.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/group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..22a39e5c97 --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,118 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + public Node(int pageNum) { + this.pageNum = pageNum; + } + } + + private int capacity; + private int curSize = 0; + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + if (first == null){ + first = new Node(pageNum); + if (last == null){ + last =first; + } + curSize++; + return; + } + if (curSize < capacity){ + Node node = new Node(pageNum); + node.next=first; + first.prev=node; + first=node; + curSize++; + return; + } + Node node = first; + // 是否已存在 + while (node.next!=null){ + if (node.pageNum == pageNum){ + // 存在即交换 + if (first.pageNum == pageNum){ + return; + } + if (node.prev!=null){ + node.prev.next=node.next; + } + if (node.next!=null){ + node.next.prev=node.prev; + } + node.prev=null; + node.next=first; + first.prev=node; + first=node; + return; + } + node=node.next; + } + // 把最后一个节节点移到开头 + node = last; + last=last.prev; + last.next=null; + node.next=first; + first.prev=node; + first=node; + node.pageNum=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(); + } + + public static void main(String[] args) { + + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + System.out.println(frame); + frame.access(2); + System.out.println(frame); + } +} diff --git a/group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LinkedList.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..f4c7556a2e --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,125 @@ +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class LinkedList implements List { + + private Node head; + + 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 void addFirst(Object o){ + + } + public void addLast(Object o){ + + } + public Object removeFirst(){ + return null; + } + public Object removeLast(){ + return null; + } + public Iterator iterator(){ + return null; + } + + + private static class Node{ + Object data; + Node next; + + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int 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){ + 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; + } +} diff --git a/group13/2931408816/lesson4/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java b/group13/2931408816/lesson4/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..8835efde3d --- /dev/null +++ b/group13/2931408816/lesson4/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.loader; + +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 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + 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 + */ + +public class MyArrayList implements MyList { + + + private int size = 0; + + private final int initialCapacity = 3; + + private Object[] elementData = new Object[100]; + + private static final Object[] EMPTY_ELEMENTDATA = {}; + + private int modCount = 0; + + /** + * һĬϳʼΪ3Ŀб + * + */ + public MyArrayList() { + elementData = new Object[initialCapacity]; + } + + /** + * һָʼĿб + * @param initialCapacity + */ + public MyArrayList(int initialCapacity) { + + if (initialCapacity < 0){ + throw new IllegalArgumentException("Illegal initialCapacity: "+ initialCapacity); + }else if(initialCapacity == 0){ + elementData = EMPTY_ELEMENTDATA; + }else{ + elementData = new Object[this.initialCapacity]; + } + } + + /** + * + * һָcollectionԪصбЩԪذոcollectionĵǵ˳ + * MySubClassMyClassࡣ + * Collection myCollection; + * Collection mySubCollection; + * ArrayList myList = new ArrayList(myCollection); + * ҲԣArrayList myList = new ArrayList(mySubCollection); + * MyClassMyClassCollectionԹArrayList + * @param c + */ + public MyArrayList(Collection c) { + elementData = c.toArray(); + if((size = elementData.length) != 0){ + //c.toArray might (incorrectly) not return Object[] (see 6260652) + //ٷbugתͲȫ + //Object[]Arrays.copyOfתΪObject[] + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class); + }else{ + elementData = EMPTY_ELEMENTDATA; + } + } + + + /** + * ָԪбָλϵԪ + * @param index + * @param element + * @return Object(ǰλڸλϵľԪ) + */ + public Object set(int index, Object element) { + if (index >= size()) + throw new RuntimeException("The Index: "+index+" is out of band."); + + Object oldValue = elementData[index]; + elementData[index] = element; + return oldValue; + } + + /** + * Ԫбβ + * @param e + */ + public void add(Object e) { + if (e == null) { + throw new RuntimeException("The value should not be null."); + } + if (size() >= initialCapacity) { + ensureCapacity(size() + 1); + } + elementData [size] = e; + size++; + } + + /** + * Ԫӵбָλ + * @param index + * @param element + */ + public void add(int index, Object o) { + if (index >= size || index < 0) + throw new RuntimeException("The Index: "+index+" is out of band."); + // 鳤Ȳ㣬ݡ + ensureCapacity(size+1); + // elementDataдIndexλÿʼΪsize-indexԪأ + // ±Ϊindex+1λÿʼµelementDataС + // ǰλڸλõԪԼкԪһλá + System.arraycopy(elementData, index, elementData, index + 1, size - index); + elementData[index] = o; + size++; + } + + + /** + * شбָλϵԪ + * @param index + * @return + */ + public Object get(int index) { + if (index >= size) { + throw new RuntimeException("The index:" + index + " is out of band."); + } + return elementData [index]; + } + + /** + * ɾָλԪ + * @param ɾԪλã0ʼ + * @return Object(ɾָλϵľԪ) + */ + public Object remove(int index) { + if (index >= size) { + throw new RuntimeException("The index:" + index + " is out of band."); + } + modCount++; + Object oldElement = elementData[index]; + //˴ȻҲSystem.arraycopy ʵ + for (int i = index; i < size - 1; i++) { + elementData [i] = elementData [i + 1]; + } + elementData [size - 1] = null; + size--; + return oldElement; + } + + /** + * ݣÿռΪ 50%+1 + * @param ǰСֵ + */ + private void ensureCapacity(int minCapacity) { + modCount++; + int oldCapacity = elementData.length; + if (minCapacity > oldCapacity) { + //λ㣬൱ڳ2Щ int newCapacity = (oldCapacity * 3)/2 + 1; + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity < minCapacity) + newCapacity = minCapacity; + elementData = Arrays.copyOf(elementData, newCapacity); + } + } + /** + * ListеԪظ. + * @return ListеԪظ + */ + public int size() { + return size; + } + + /** + * ListԪеһ + * @return ListԪеĵ + */ + public Iterator iterator() { + return new Itr(); + } + + private class Itr implements Iterator { + int cursor; // һԪصλ + int lastRet = -1; // һԪصλ + int expectedModCount = modCount; + + public boolean hasNext() { + return cursor != size; + } + + public Object next() { + + if (modCount != expectedModCount){ + throw new RuntimeException("This list is being modified."); + + } + + int i = cursor; + if (i >= size){ + throw new RuntimeException("No such element."); + } + Object[] elementData = MyArrayList.this.elementData; + if (i >= elementData.length){ + throw new RuntimeException("This list is being modified."); + } + + cursor = i + 1; + return elementData[lastRet = i]; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + + if (modCount != expectedModCount){ + throw new RuntimeException("This list is being modified."); + + } + + try { + MyArrayList.this.remove(lastRet); + cursor = lastRet; + lastRet = -1; + expectedModCount = modCount; + } catch (IndexOutOfBoundsException ex) { + throw new RuntimeException("This list is being modified."); + } + } + } + +} diff --git a/group13/413007522/dataStructure/MyBinaryTree.java b/group13/413007522/dataStructure/MyBinaryTree.java new file mode 100644 index 0000000000..eb836db4d2 --- /dev/null +++ b/group13/413007522/dataStructure/MyBinaryTree.java @@ -0,0 +1,10 @@ +package cn.xl.c1; + +public class MyBinaryTree { + + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +} diff --git a/group13/413007522/dataStructure/MyIterator.java b/group13/413007522/dataStructure/MyIterator.java new file mode 100644 index 0000000000..4e3ed63f16 --- /dev/null +++ b/group13/413007522/dataStructure/MyIterator.java @@ -0,0 +1,10 @@ +package cn.xl.c1; + +public class MyIterator { + + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +} diff --git a/group13/413007522/dataStructure/MyLinkedList.java b/group13/413007522/dataStructure/MyLinkedList.java new file mode 100644 index 0000000000..2eff03b770 --- /dev/null +++ b/group13/413007522/dataStructure/MyLinkedList.java @@ -0,0 +1,218 @@ +package cn.xl.c1; + +import java.util.Iterator; + +/** + * + * @author XIAOLONG + * @param + * + */ +public class MyLinkedList implements MyList { + + private int size = 0; + + private Node first; + + private Node last; + + + /** + * һ޲ι캯һList + * + */ + public MyLinkedList(){ + + } + + + + /** + * Ԫбβ + * @param Object(ӵԪ) + */ + public void add(Object o) { + + addLast(o); + } + + + /** + * бָλԪ,ǾԪ + * @param index λãObject Ԫ + */ + public void add(int index, Object o) { + + if(!(index >= 0 && index <= size())){ + throw new RuntimeException("The index"+index+"is out of band."); + } + + Node x = node(index); + x.data = o; + + } + + /** + * ȡָλõԪdata + * @param index ҪȡԪλ + */ + public Object get(int index) { + + if(!(index >= 0 && index <= size())){ + throw new RuntimeException("The index"+index+"is out of band."); + } + + return node(index).data; + } + + + /** + * ɾָλԪ + * @param index ɾбԪλ + */ + public Object remove(int index) { + + if(!(index >= 0 && index <= size())){ + throw new RuntimeException("The index"+index+"is out of band."); + } + + final Node node = node(index); + final Object o = node.data; + if(first.equals(node)){ + removeFirst(); + }else if(last.equals(node)){ + removeLast(); + }else{ + final Node prev = node.prev; + final Node next = node.next; + + prev.next = next; + next.prev = prev; + node.prev = null; + node.next = null; + } + node.data = null; + size --; + return o; + } + + + /** + * ȡбǰsize + */ + public int size() { + return size; + } + + /** + * ͷԪ,ͷԪΪգøԪͬʱΪβԪ + * @param Object ӵͷԪأ + */ + public void addFirst(Object o){ + + final Node f = first; + final Node newNode = new Node(null,o,f); + if(f == null){ + last = newNode; + }else{ + f.prev = newNode; + } + size ++; + } + + /** + * βԪأβԪΪգͬʱøԪΪͷԪ + * @param Object(ӵβԪ) + */ + public void addLast(Object o){ + + final Node l = last; + final Node newNode = new Node(l,o,null); + if(l == null){ + first = newNode; + }else{ + l.next = newNode; + } + size ++; + } + + /** + * ƳһԪأƳԺбΪ first = next = null + * @return ƳԪ + */ + public Object removeFirst(){ + + final Node f = first; + final Object o = f.data; + final Node next = f.next ; + f.next = null; + f.data = null; + first = next; + if(next == null){ + last = next; + }else{ + next.prev = null; + } + size --; + return o; + } + + /** + * ƳһԪ + * @return ƳԪ + */ + public Object removeLast(){ + + final Node l = last; + final Object o = l.data; + final Node prev = l.prev; + l.data = null; + l.prev = null; + last = prev; + if(prev == null){ + last = null; + }else{ + prev.next = null; + } + size --; + return o; + } + public Iterator iterator(){ + return null; + } + + /** + * Nodeڲ + * + */ + private static class Node{ + Object data; + Node next; + Node prev; + + Node(Node prev,Object o,Node next){ + this.data = o; + this.next = next; + this.prev = prev; + } + } + + /** + * һȡ±λnodeķ + * ǰ±Сlistȵһ䣬ͷʼ βʼ + * @param index Ԫصλ + */ + private Node node(int index){ + if (index < (size >> 1)) { + Node x = first; + for (int i = 0; i < index; i++) + x = x.next; + return x; + } else { + Node x = last; + for (int i = size - 1; i > index; i--) + x = x.prev; + return x; + } + } +} diff --git a/group13/413007522/dataStructure/MyList.java b/group13/413007522/dataStructure/MyList.java new file mode 100644 index 0000000000..64b7179c01 --- /dev/null +++ b/group13/413007522/dataStructure/MyList.java @@ -0,0 +1,10 @@ + +package cn.xl.c1; + +public interface MyList { + 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(); +} \ No newline at end of file diff --git a/group13/413007522/dataStructure/MyQueue.java b/group13/413007522/dataStructure/MyQueue.java new file mode 100644 index 0000000000..99fcd742db --- /dev/null +++ b/group13/413007522/dataStructure/MyQueue.java @@ -0,0 +1,137 @@ +package cn.xl.c1; + +/** + * Queue一个先进先出(first in first out,FIFO)得队列 + * 所谓的队列,也是一个含有至少两个基本操作的抽象数据类型:插入新的元素;删除最久时间插入的元素。 + * 遵循FIFO(First in,first out,先进先出)的原则。 + * MyQueue采用环形数组实现 + * @author XIAOLONG + * + */ +public class MyQueue { + + private int size,head,tail; + + private Object[] elementData; + + private final int initialCapacity = 4; + + public MyQueue(){ + + head = tail = -1; + elementData = new Object[initialCapacity]; + + } + + /** + * 向队列中添加元素 + * @param o + */ + public void enQueue(Object o){ + + ensureCapacity(); + + if( head == -1) { + tail = head = 0; + } + size ++; + elementData[tail] = o; + tail ++; + + + } + + /** + * 删除栈顶元素,并返回旧栈顶元素 + * @return 旧栈顶元素 + */ + public Object deQueue(){ + Object element = elementData[head]; + if(head == tail){ + head = tail = -1; + }else if(head == elementData.length-1){ + head = 0; + }else{ + head ++; + } + size --; + return element; + } + + /** + * 判断队列是否为空 + * @return + */ + public boolean isEmpty(){ + return head == -1; + } + + /** + * 返回自身长度 + * @return + */ + public int size(){ + return size; + } + + /** + * 判断队列是否已满 + * @return + */ + public boolean isFull() { + return (head == 0 && tail == elementData.length); + } + + /** + * 扩展容量,如果队列有效数据已经占满空间则增加2,否则覆盖无效数据,重新分配数据空间 + * @param 当前队列所需最小容量size + */ + private void ensureCapacity(){ + + if(isFull()){ + Object [] oldData = elementData; + elementData = new Object[elementData.length + 2]; + System.arraycopy(oldData, head,elementData , 0, oldData.length); + }else if(head > 0){ + Object [] oldData = elementData; + System.arraycopy(oldData, head,elementData , 0, oldData.length-head); + tail = tail - head ; + head = 0; + } + } + + + public void printAll() { + for(Object i:elementData) + System.out.print(i+" "); + System.out.println(); + } + public static void main(String[] args) + { + MyQueue se=new MyQueue(); + se.enQueue(1); + se.enQueue(2); + se.enQueue(3); + se.enQueue(4); + System.out.println("原始容量下,队列元素为"); + se.printAll(); + + System.out.println("队列满后,继续增加元素5"); + se.enQueue(5); + se.printAll(); + + se.deQueue(); + System.out.println("删除队列首元素1,队列首元素为:"+se.elementData[se.head]); + + se.deQueue(); + + se.enQueue(6); + se.enQueue(7); + se.enQueue(8); + se.enQueue(9); + se.enQueue(10); + se.enQueue(11); + se.printAll(); + + } +} diff --git a/group13/413007522/dataStructure/MyStack.java b/group13/413007522/dataStructure/MyStack.java new file mode 100644 index 0000000000..c28e6b60ac --- /dev/null +++ b/group13/413007522/dataStructure/MyStack.java @@ -0,0 +1,124 @@ +package cn.xl.c1; + +import java.util.Arrays; +import java.util.EmptyStackException; + +/** + * Stackһȳlast in first outLIFOĶջ + * VectorĻչ5 + * @author XIAOLONG + * + */ +public class MyStack { + + private int elementCount; + + private Object[] elementData; + + /** + * ޲ι췽һջ + * + */ + public MyStack(){ + + } + + + /** + * Ԫջ + * @param item + * @return ջԪ + */ + public synchronized Object push(Object item){ + + ensureCapacity(elementCount+1); + elementData[elementCount] = item; + elementCount ++; + return item; + } + + /** + * ջԪƳظԪ + * @return ջԪ + */ + public synchronized Object pop(){ + Object obj; + + obj = peek(); + elementCount --; + elementData[elementCount] = null; + + return obj; + } + + /** + * 鿴ջԪ + * + * @return ջԪ + * @throws ջΪ ׳ EmptyStackException쳣 . + */ + public synchronized Object peek(){ + int len = elementCount; + + if(len == 0) + throw new EmptyStackException(); + + return elementData[len - 1]; + + } + + /** + * ջǷΪ + * + * @return True or false + */ + public boolean isEmpty(){ + + return elementCount == 0; + } + + /** + * ѯռջǷijԪ + * @param ѯԪ + * @return ԪشڷԪλãջԪλΪ1 + * Ԫջظ򷵻ؾջԪλã + * Ԫջвڣ򷵻 -1 + */ + public synchronized int search(Object o){ + + if(o == null){ + for(int i = elementCount -1;i >= 0; i--){ + if(elementData[i] == null){ + return elementCount - i; + } + } + }else{ + for(int i = elementCount -1;i >= 0; i-- ){ + if(o.equals(elementData[i])){ + return elementCount - i; + } + } + } + + return -1; + } + + /** + * չһ + * @param ǰջСsize + */ + private void ensureCapacity(int minCapacity){ + int oldCapacity = elementData.length; + if(minCapacity > oldCapacity){ + int newCapacity = oldCapacity << 1; + elementData = Arrays.copyOf(elementData, newCapacity); + } + } + + public static void main(String[] args){ + + + + } + +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadStartup.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadStartup.java new file mode 100644 index 0000000000..cbbb593cc9 --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadStartup.java @@ -0,0 +1,14 @@ +package cn.xl.c3; + +public class DownloadStartup { + private static final String encoding = "utf-8"; + + public static void main(String[] args) { + DownloadTask downloadManager = new DownloadTask(5); + String urlStr = "http://imgadmin.voole.com/img/pic/2017/03/21/1000/2017032117552710008ww5f.jpg"; + //downloadManager.setThreadNum(1); + downloadManager.setSleepSeconds(5); + downloadManager.setFileDir("E://"); + downloadManager.download(urlStr, encoding); + } +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadTask.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadTask.java new file mode 100644 index 0000000000..624414daa2 --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadTask.java @@ -0,0 +1,411 @@ +package cn.xl.c3; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +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.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class DownloadTask { + public void download(String urlStr, String charset) { + this.charset = charset; + long contentLength = 0; + CountDownLatch latch = new CountDownLatch(threadNum); + long[] startPos = new long[threadNum]; + long endPos = 0; + + + try { + // urlлصļʽ + //String fileSeparator = System.getProperty("file.separator"); + this.fileName = urlStr.substring(urlStr.lastIndexOf("/") + 1); + + this.url = new URL(urlStr); + URLConnection con = url.openConnection(); + setHeader(con); + // õcontentij + contentLength = con.getContentLength(); + // contextΪthreadNumεĻÿεijȡ + this.threadLength = contentLength / threadNum; + + // һصʱļöϵ㣬µĿļڵ4˵ + startPos = setThreadBreakpoint(fileDir, fileName, contentLength, startPos); + + //ڶֶ߳ļ + ExecutorService exec = Executors.newCachedThreadPool(); + for (int i = 0; i < threadNum; i++) { + // ߳ݣÿݵʼλΪ(threadLength * i + س) + startPos[i] += threadLength * i; + + /**//*̵ֹ߳λãһ̼߳Ϊ(threadLength * (i + 1) - 1) + һ̵ֹ߳λüΪݵij*/ + if (i == threadNum - 1) { + endPos = contentLength; + } else { + endPos = threadLength * (i + 1) - 1; + } + // ִ̣߳С + ChildThread thread = new ChildThread(this, latch, i, startPos[i], endPos); + childThreads[i] = thread; + exec.execute(thread); + } + + try { + // ȴCountdownLatchźΪ0ʾ̶߳ + latch.await(); + exec.shutdown(); + + // ѷֶʱļедĿļСڵ3˵ + tempFileToTargetFile(childThreads); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + + ///////// + private long[] setThreadBreakpoint(String fileDir2, String fileName2, + long contentLength, long[] startPos) { + File file = new File(fileDir + fileName); + long localFileSize = file.length(); + + if (file.exists()) { + System.out.println("file " + fileName + " has exists!"); + // صĿļѴڣжĿļǷ + if (localFileSize < contentLength) { + System.out.println("Now download continue "); + + // Ŀļʱļöϵλãÿʱļij + File tempFileDir = new File(fileDir); + File[] files = tempFileDir.listFiles(); + for (int k = 0; k < files.length; k++) { + String tempFileName = files[k].getName(); + // ʱļʽΪĿļ+"_"+ + if (tempFileName != null && files[k].length() > 0 + && tempFileName.startsWith(fileName + "_")) { + int fileLongNum = Integer.parseInt(tempFileName + .substring(tempFileName.lastIndexOf("_") + 1, + tempFileName.lastIndexOf("_") + 2)); + // Ϊÿ߳صλ + startPos[fileLongNum] = files[k].length(); + } + } + } + } else { + // صĿļڣ򴴽ļ + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return startPos; + } + + //// + private void setHeader(URLConnection con) { + con.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3"); + con.setRequestProperty("Accept-Language", "en-us,en; q=0.7,zh-cn; q=0.3"); + con.setRequestProperty("Accept-Encoding", "aa"); + con.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8; q=0.7,*; q=0.7"); + con.setRequestProperty("Keep-Alive", "300"); + con.setRequestProperty("Connection", "keep-alive"); + con.setRequestProperty("If-Modified-Since", "Fri, 02 Jan 2009 17:00:05 GMT"); + con.setRequestProperty("If-None-Match", "\"1261d8-4290-df64d224\""); + con.setRequestProperty("Cache-Control", "max-age=0"); + con.setRequestProperty("Referer", "http://http://www.bt285.cn"); + } + + /// + private void tempFileToTargetFile(ChildThread[] childThreads) { + try { + BufferedOutputStream outputStream = new BufferedOutputStream( + new FileOutputStream(fileDir + fileName)); + + // ̴߳ʱļ˳дĿļ + for (int i = 0; i < threadNum; i++) { + if (statusError) { + for (int k = 0; k < threadNum; k++) { + if (childThreads[k].tempFile.length() == 0) + childThreads[k].tempFile.delete(); + } + System.out.println("񲻳ɹ߳"); + break; + } + + BufferedInputStream inputStream = new BufferedInputStream( + new FileInputStream(childThreads[i].tempFile)); + System.out.println("Now is file " + childThreads[i].id); + int len = 0; + int count = 0; + byte[] b = new byte[1024]; + while ((len = inputStream.read(b)) != -1) { + count += len; + outputStream.write(b, 0, len); + if ((count % 5000) == 0) { + outputStream.flush(); + } + + // b = new byte[1024]; + } + + inputStream.close(); + // ɾʱļ + if (childThreads[i].status == ChildThread.STATUS_HAS_FINISHED) { + childThreads[i].tempFile.delete(); + } + } + + outputStream.flush(); + outputStream.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + //////// + class ChildThread extends Thread { + public static final int STATUS_HASNOT_FINISHED = 0; + public static final int STATUS_HAS_FINISHED = 1; + public static final int STATUS_HTTPSTATUS_ERROR = 2; + private DownloadTask task; + private int id; + private long startPosition; + private long endPosition; + private final CountDownLatch latch; + private File tempFile = null; + // ߳״̬ + private int status = ChildThread.STATUS_HASNOT_FINISHED; + + public ChildThread(DownloadTask task, CountDownLatch latch, int id, long startPos, long endPos) { + super(); + this.task = task; + this.id = id; + this.startPosition = startPos; + this.endPosition = endPos; + this.latch = latch; + + try { + tempFile = new File(this.task.fileDir + this.task.fileName + "_" + id); + if(!tempFile.exists()){ + tempFile.createNewFile(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public void run() { + System.out.println("Thread " + id + " run "); + HttpURLConnection con = null; + InputStream inputStream = null; + BufferedOutputStream outputStream = null; + int count = 0; + long threadDownloadLength = endPosition - startPosition; + + try { + outputStream = new BufferedOutputStream(new FileOutputStream(tempFile.getPath(), true)); + } catch (FileNotFoundException e2) { + e2.printStackTrace(); + } + + for(; ; ){ + startPosition += count; + try { + // URLConnection + con = (HttpURLConnection) task.url.openConnection(); + setHeader(con); + con.setAllowUserInteraction(true); + // ӳʱʱΪ10000ms + con.setConnectTimeout(10000); + // öȡݳʱʱΪ10000ms + con.setReadTimeout(10000); + + if(startPosition < endPosition){ + // ݵֹ + con.setRequestProperty("Range", "bytes=" + startPosition + "-" + + endPosition); + System.out.println("Thread " + id + " startPosition is " + startPosition); + System.out.println("Thread " + id + " endPosition is " + endPosition); + + // жhttp statusǷΪHTTP/1.1 206 Partial Content200 OK + // ״̬statusΪSTATUS_HTTPSTATUS_ERROR + if (con.getResponseCode() != HttpURLConnection.HTTP_OK + && con.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) { + System.out.println("Thread " + id + ": code = " + + con.getResponseCode() + ", status = " + + con.getResponseMessage()); + status = ChildThread.STATUS_HTTPSTATUS_ERROR; + this.task.statusError = true; + outputStream.close(); + con.disconnect(); + System.out.println("Thread " + id + " finished."); + latch.countDown(); + break; + } + + inputStream = con.getInputStream(); + + int len = 0; + byte[] b = new byte[1024]; + while ((len = inputStream.read(b)) != -1) { + outputStream.write(b, 0, len); + count += len; + + // ÿ5000byteflushһ + if(count % 5000 == 0){ + outputStream.flush(); + } + } + + System.out.println("count is " + count); + if(count >= threadDownloadLength){ + //hasFinished = true; + } + outputStream.flush(); + outputStream.close(); + inputStream.close(); + con.disconnect(); + } + + this.status = this.STATUS_HAS_FINISHED; + //System.out.println("Thread " + id + " finished."); + latch.countDown(); + break; + } catch (IOException e) { + try { + outputStream.flush(); + TimeUnit.SECONDS.sleep(getSleepSeconds()); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } catch (IOException e2) { + e2.printStackTrace(); + } + continue; + } + } + } + } + + public DownloadTask(int threadNum){ + childThreads= new ChildThread[threadNum]; + this.threadNum = threadNum; + } + + + + private String charset; + private int threadNum; + private String fileName; + private URL url; + private Long threadLength; + private String fileDir; + private ChildThread[] childThreads ; + private boolean statusError; + private int SleepSeconds; + public String getCharset() { + return charset; + } + + + public void setCharset(String charset) { + this.charset = charset; + } + + + public int getThreadNum() { + return threadNum; + } + + + public void setThreadNum(int threadNum) { + this.threadNum = threadNum; + } + + + public String getFileName() { + return fileName; + } + + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + + public URL getUrl() { + return url; + } + + + public void setUrl(URL url) { + this.url = url; + } + + + public Long getThreadLength() { + return threadLength; + } + + + public void setThreadLength(Long threadLength) { + this.threadLength = threadLength; + } + + + public String getFileDir() { + return fileDir; + } + + + public void setFileDir(String fileDir) { + this.fileDir = fileDir; + } + + + public boolean isStatusError() { + return statusError; + } + + + public void setStatusError(boolean statusError) { + this.statusError = statusError; + } + + + public int getSleepSeconds() { + return SleepSeconds; + } + + + public void setSleepSeconds(int sleepSeconds) { + SleepSeconds = sleepSeconds; + } + + +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadThread.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadThread.java new file mode 100644 index 0000000000..d50c0d3307 --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadThread.java @@ -0,0 +1,113 @@ +package cn.xl.c3; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URLConnection; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeUnit; + +import cn.xl.c3.DownloadTask.ChildThread; +import cn.xl.c3.api.Connection; + +public class DownloadThread extends Thread{ + + public static final int STATUS_HASNOT_FINISHED = 0; + public static final int STATUS_HAS_FINISHED = 1; + public static final int STATUS_HTTPSTATUS_ERROR = 2; + Connection conn; + int startPos; + int endPos; + int id; + DownloadTask task; + CountDownLatch latch; + File tempFile = null; + // 线程状态码 + public int status = ChildThread.STATUS_HASNOT_FINISHED; + + public DownloadThread( String filePath, Connection conn,int id, int startPos, int endPos, CountDownLatch latch){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.latch = latch; + this.id = id; + try { + tempFile = new File(filePath + "_" + id); + if(!tempFile.exists()){ + tempFile.createNewFile(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + + } + + + public void run(){ + + try { + + InputStream inputStream = null; + BufferedOutputStream outputStream = null; + int count = 0; + long threadDownloadLength = endPos - startPos; + + try { + outputStream = new BufferedOutputStream(new FileOutputStream(tempFile.getPath(), true)); + } catch (FileNotFoundException e2) { + e2.printStackTrace(); + } + + for(; ; ){ + startPos += count; + + System.out.println("the id="+id+"thread ,startPos:"+startPos); + System.out.println("the id="+id+"thread ,endPos:"+endPos); + + inputStream = conn.getInputStream(startPos,endPos); + + int len = 0; + byte[] b = new byte[1024]; + while ((len = inputStream.read(b)) != -1) { + outputStream.write(b, 0, len); + count += len; + + // 每读满5000个byte,往磁盘上flush一下 + if(count % 5000 == 0){ + outputStream.flush(); + } + } + + System.out.println("count is " + count); + if(count >= threadDownloadLength){ + //hasFinished = true; + } + outputStream.flush(); + outputStream.close(); + inputStream.close(); + + this.status = this.STATUS_HAS_FINISHED; + //System.out.println("Thread " + id + " finished."); + latch.countDown(); + break; + + } + + + this.status = this.STATUS_HAS_FINISHED; + latch.countDown(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloader.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloader.java new file mode 100644 index 0000000000..df7b2b22ec --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloader.java @@ -0,0 +1,215 @@ +package cn.xl.c3; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import cn.xl.c3.DownloadTask.ChildThread; +import cn.xl.c3.api.Connection; +import cn.xl.c3.api.ConnectionException; +import cn.xl.c3.api.ConnectionManager; +import cn.xl.c3.api.DownloadListener; + +public class FileDownloader { + + private String url; + + private String fileName; + + private int threadLength; + + private String fileDir; + + private static final int DOWNLOAD_TRHEAD_NUM = 4; + + private DownloadThread[] childThreads ; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url,String _fileDir) { + this.url = _url; + this.fileDir = _fileDir; + } + + public void execute(){ + + + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_TRHEAD_NUM , new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }); + + + Connection conn = null; + int[] startPos = new int[DOWNLOAD_TRHEAD_NUM]; + CountDownLatch latch = new CountDownLatch(DOWNLOAD_TRHEAD_NUM); + childThreads = new DownloadThread[DOWNLOAD_TRHEAD_NUM]; + int endPos = 0; + this.fileName = url.substring(url.lastIndexOf("/") + 1); + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + System.out.println("length===="+length); + + this.threadLength = length / DOWNLOAD_TRHEAD_NUM; + + ExecutorService exec = Executors.newCachedThreadPool(); + + // 第一步,分析已下载的临时文件,设置断点,如果是新的下载任务,则建立目标文件。在第4点中说明。 + startPos = setThreadBreakpoint(fileDir, fileName, length, startPos); + + for (int i = 0; i < DOWNLOAD_TRHEAD_NUM; i++) { + startPos[i] += threadLength * i; + if (i == DOWNLOAD_TRHEAD_NUM - 1) { + endPos = length; + } else { + endPos = threadLength * (i + 1) - 1; + } + DownloadThread downloadThread = new DownloadThread( + fileDir+fileName, + cm.open(this.url), + i, + startPos[i], + endPos, + latch); + + childThreads[i] = downloadThread; + exec.execute(downloadThread); + } + + try { + latch.await(); + exec.shutdown(); + tempFileToTargetFile(childThreads); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + + } + } + + } + + private void tempFileToTargetFile(DownloadThread[] childThreads) { + try { + BufferedOutputStream outputStream = new BufferedOutputStream( + new FileOutputStream(fileDir + fileName)); + + // 遍历所有子线程创建的临时文件,按顺序把下载内容写入目标文件中 + for (int i = 0; i < DOWNLOAD_TRHEAD_NUM; i++) { + /*if (statusError) { + for (int k = 0; k < threadNum; k++) { + if (childThreads[k].tempFile.length() == 0) + childThreads[k].tempFile.delete(); + } + System.out.println("本次下载任务不成功,请重新设置线程数。"); + break; + } */ + + BufferedInputStream inputStream = new BufferedInputStream( + new FileInputStream(childThreads[i].tempFile)); + System.out.println("Now is file " + childThreads[i].id); + int len = 0; + int count = 0; + byte[] b = new byte[1024]; + while ((len = inputStream.read(b)) != -1) { + count += len; + outputStream.write(b, 0, len); + if ((count % 5000) == 0) { + outputStream.flush(); + } + + // b = new byte[1024]; + } + + inputStream.close(); + childThreads[i].tempFile.delete(); + // 删除临时文件 + /*if (childThreads[i].status == ChildThread.STATUS_HAS_FINISHED) { + childThreads[i].tempFile.delete(); + } */ + } + + outputStream.flush(); + outputStream.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + private int[] setThreadBreakpoint(String fileDir2, String fileName2, + int contentLength, int[] startPos) { + File file = new File(fileDir + fileName); + long localFileSize = file.length(); + + if (file.exists()) { + System.out.println("file " + fileName + " has exists!"); + // 下载的目标文件已存在,判断目标文件是否完整 + if (localFileSize < contentLength) { + System.out.println("Now download continue "); + + // 遍历目标文件的所有临时文件,设置断点的位置,即每个临时文件的长度 + File tempFileDir = new File(fileDir); + File[] files = tempFileDir.listFiles(); + for (int k = 0; k < files.length; k++) { + String tempFileName = files[k].getName(); + // 临时文件的命名方式为:目标文件名+"_"+编号 + if (tempFileName != null && files[k].length() > 0 + && tempFileName.startsWith(fileName + "_")) { + int fileLongNum = Integer.parseInt(tempFileName + .substring(tempFileName.lastIndexOf("_") + 1, + tempFileName.lastIndexOf("_") + 2)); + // 为每个线程设置已下载的位置 + startPos[fileLongNum] = (int) files[k].length(); + } + } + } + } else { + // 如果下载的目标文件不存在,则创建新文件 + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return startPos; + } + + + 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/group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloaderTest.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloaderTest.java new file mode 100644 index 0000000000..df2d0f6d70 --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloaderTest.java @@ -0,0 +1,63 @@ +package cn.xl.c3; + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import cn.xl.c3.api.ConnectionManager; +import cn.xl.c3.api.DownloadListener; +import cn.xl.c3.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://image11.m1905.cn/uploadfile/2015/0211/thumb_1___3_20150211064226697882.jpg"; + String url = "http://imgadmin.voole.com/img/pic/2017/03/21/1000/2017032117552710008ww5f.jpg"; + + String filePath = "E:/test/"; + + FileDownloader downloader = new FileDownloader(url,filePath); + + 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/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/Connection.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/Connection.java new file mode 100644 index 0000000000..90b52b215f --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/Connection.java @@ -0,0 +1,31 @@ +package cn.xl.c3.api; +import java.io.IOException; +import java.io.InputStream; + +public interface Connection { + + + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + /** + * + * + */ + public InputStream getInputStream(int startPos, int endPos); + + + public void close(); + + + +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionException.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionException.java new file mode 100644 index 0000000000..799a9a4675 --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionException.java @@ -0,0 +1,5 @@ +package cn.xl.c3.api; + +public class ConnectionException extends Exception { + +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionManager.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionManager.java new file mode 100644 index 0000000000..95073321b8 --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package cn.xl.c3.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/DownloadListener.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/DownloadListener.java new file mode 100644 index 0000000000..bc233c01de --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/api/DownloadListener.java @@ -0,0 +1,5 @@ +package cn.xl.c3.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionImpl.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionImpl.java new file mode 100644 index 0000000000..18f29ca6df --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionImpl.java @@ -0,0 +1,116 @@ +package cn.xl.c3.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 cn.xl.c3.api.Connection; +import cn.xl.c3.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) { + + } + } + + @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(); + + + /*byte[] b = new byte[endPos - startPos + 1]; + + is.read(b, 0, endPos - startPos + 1); + + is.close(); + + return b;*/ + + 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); + } + + /*is.close(); + baos.close(); + httpConn.disconnect();*/ + return baos.toByteArray(); + } + + + @Override + public int getContentLength() { + + URLConnection con; + try { + con = url.openConnection(); + return con.getContentLength(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return -1; + } + + @Override + public InputStream getInputStream(int startPos, int endPos){ + + HttpURLConnection httpConn = null; + InputStream is = null; + try { + httpConn = (HttpURLConnection)url.openConnection(); + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + + endPos); + is = httpConn.getInputStream(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + //if(httpConn != null) httpConn.disconnect(); + + return is; + } + + @Override + public void close() { + // TODO Auto-generated method stub + + + } + +} diff --git a/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionManagerImpl.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..e5bd712bfb --- /dev/null +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionManagerImpl.java @@ -0,0 +1,19 @@ +package cn.xl.c3.impl; + + +import cn.xl.c3.api.Connection; +import cn.xl.c3.api.ConnectionException; +import cn.xl.c3.api.ConnectionManager; + + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return new ConnectionImpl(url); + } + + + +} diff --git a/group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrame.java b/group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..1985dae3fc --- /dev/null +++ b/group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrame.java @@ -0,0 +1,127 @@ +package cn.xl.basic.linklist; + +/** + * 用双向链表实现LRU(Least Recently Used 近期最少使用算法) + * @author CoderXLoong + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(Node _prev,int _pageNum,Node _next) { + this.prev = _prev; + this.pageNum = _pageNum; + this.next = _next; + } + } + + private int capacity; + private int size; + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + + if(first != null && first.pageNum == pageNum){ + return; + } + + removeNode(pageNum); + if(size()+1 > capacity){ + removeLast(); + } + addFirst(pageNum); + + } + + + + private int size(){ + return size; + } + + + private void addFirst(int pageNum){ + final Node f = first; + final Node newNode = new Node(null,pageNum,f); + if(f == null){ + last = newNode; + }else{ + f.prev = newNode; + } + first = newNode; + size++; + } + + + private void removeLast(){ + + final Node l = last; + final Node prev = l.prev; + prev.next = null; + l.prev = null; + last = prev; + size --; + } + + + private void removeNode(int pageNum){ + Node node = first; + while(node != null){ + if(node.pageNum == pageNum){ + if(node == last){ + removeLast(); + }else{ + final Node prev = node.prev; + final Node next = node.next; + prev.next = next; + next.prev = prev; + node.prev = null; + node.next = null; + size--; + } + break; + }else{ + node = node.next; + } + } + + + } + + + + 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/group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrameTest.java b/group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..e6f073d942 --- /dev/null +++ b/group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package cn.xl.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/group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/ClassFileLoader.java b/group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..a8655a919f --- /dev/null +++ b/group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/ClassFileLoader.java @@ -0,0 +1,69 @@ +package cn.xl.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + + System.out.println("解析Class文件路径:"+getClassPath()+"/"+className.replace('.', '/')+".class"); + + File file = new File(getClassPath()+"/"+className.replace('.', '/')+".class"); + // 如果不存在直接返回 + if (!file.exists()) { + return null; + } + InputStream in = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + // 一次读一个字节 + in = new FileInputStream(file); + int tempbyte; + while ((tempbyte = in.read()) != -1) { + baos.write(tempbyte); + } + in.close(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + return baos.toByteArray(); + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuffer sbf = new StringBuffer(); + if(clzPaths.size() >= 1){ + sbf.append(clzPaths.get(0)); + } + for(int i = 1; i < clzPaths.size(); i++){ + sbf.append(";"); + sbf.append(clzPaths.get(i)); + } + + return sbf.toString(); + + } + + + +} diff --git a/group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/EmployeeV1.java b/group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/EmployeeV1.java new file mode 100644 index 0000000000..93642d6066 --- /dev/null +++ b/group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/EmployeeV1.java @@ -0,0 +1,28 @@ +package cn.xl.jvm.loader; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group13/413007522/lesson04/src/test/java/jvm/loader/ClassFileloaderTest.java b/group13/413007522/lesson04/src/test/java/jvm/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..f3b2160c40 --- /dev/null +++ b/group13/413007522/lesson04/src/test/java/jvm/loader/ClassFileloaderTest.java @@ -0,0 +1,93 @@ +package jvm.loader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import cn.xl.jvm.loader.ClassFileLoader; + + + + + + +public class ClassFileloaderTest { + + + static String path1 = "D:/trainingworkspace/lesson01/target/classes"; + static String path2 = "D://??"; + + + + @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 = "cn.xl.jvm.loader.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1042, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "cn.xl.jvm.loader.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 list2=new LinkedList<>(); + LinkedList list2=new LinkedList<>(); list2.add(0); list2.add(1); list2.add(2); + list2.add(2); + System.out.println(list2.indexOf(2)); - list2.addLast(3); - list2.remove(0); +// list2.addLast(3); +// list2.remove(0); //list2.removeFirst(); - Iterator ite2=list2.iterator(); - ite2.next(); + /*Iterator ite2=list2.iterator(); while(ite2.hasNext()){ System.out.println(ite2.next()); }*/ - - + } + @Test + public void testArrayList() { //ArrayList - /*ArrayList list1=new ArrayList(); + ArrayList list1=new ArrayList(); + list1.contains(3); list1.add(0); list1.add(1); //list1.add(3, -1);//error @@ -48,6 +62,8 @@ public static void main(String[] args) { Iterator ite=list1.iterator(); while(ite.hasNext()){ System.out.println(ite.next()); - }*/ + } + fail("Not yet implemented"); } + } diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/DownloadThread.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/DownloadThread.java new file mode 100644 index 0000000000..8ab66288b0 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/DownloadThread.java @@ -0,0 +1,70 @@ +package com.m0312.download; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.m0312.download.api.Connection; +import com.m0312.download.api.DownloadListener; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String descFilePath; + private CyclicBarrier cyclicBarrier; + + public DownloadThread( Connection conn, int startPos, int endPos){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public DownloadThread( Connection conn, int startPos, int endPos, + String descFilePath,CyclicBarrier cyclicBarrier){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.descFilePath=descFilePath; + this.cyclicBarrier=cyclicBarrier; + } + @Override + public void run(){ + try { + /*byte[] bytes=conn.read(startPos, endPos); + os=new FileOutputStream(new File(descFilePath)); + os.write(bytes, startPos, endPos-startPos+1); + cyclicBarrier.await();//等待其他线程 + */ + byte[] buffer = conn.read(startPos , endPos); + RandomAccessFile file = new RandomAccessFile(descFilePath, "rw"); + file.seek(startPos); + file.write(buffer, 0, buffer.length); + file.close(); + cyclicBarrier.await(); + + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + System.out.println("所有线程都下载完成"); + //通知 FileDownloader ,自己已经做完 + + } +} + + + + + + + diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloader.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloader.java new file mode 100644 index 0000000000..b6d9102f96 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloader.java @@ -0,0 +1,129 @@ +package com.m0312.download; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.m0312.download.api.Connection; +import com.m0312.download.api.ConnectionException; +import com.m0312.download.api.ConnectionManager; +import com.m0312.download.api.DownloadListener; +import com.test.downfile.DownThread; + + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + private static final int THREAD_NUM = 3; + + //定义几个线程去下载 + final int DOWN_THREAD_NUM = 3; + final String OUT_FILE_NAME = "e:/testfile/down.png"; + InputStream[] isArr = new InputStream[DOWN_THREAD_NUM]; + RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM]; + + 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(); + String filename=url.substring(url.lastIndexOf("/")); + String descFilePath="E://testfile//"+filename; + + CyclicBarrier barrier=new CyclicBarrier(THREAD_NUM,new Runnable() { + @Override + public void run() { + listener.notifyFinished(); + + } + }); + /*int every=length/3; + new DownloadThread(conn,0,every-1,descFilePath,barrier).start(); + new DownloadThread(conn,every,every*2-1,descFilePath,barrier).start(); + new DownloadThread(conn,every*2,length-1,descFilePath,barrier).start();*/ + + + isArr[0] = conn.getUrlCon().getInputStream(); + int fileLen = conn.getContentLength(); + System.out.println("网络资源的大小" + fileLen); + + // 每线程应该下载的字节数 + long numPerThred = fileLen / DOWN_THREAD_NUM; + // 整个下载资源整除后剩下的余数取模 + long left = fileLen % DOWN_THREAD_NUM; + int start=0; + int end=0; + for (int i = 0; i < DOWN_THREAD_NUM; i++) { + + // 为每个线程打开一个输入流、一个RandomAccessFile对象, + // 让每个线程分别负责下载资源的不同部分。 + //isArr[0]和outArr[0]已经使用,从不为0开始 + + // 分别启动多个线程来下载网络资源 + if (i == DOWN_THREAD_NUM - 1) { + // 最后一个线程下载指定numPerThred+left个字节 + start=(int) (i * numPerThred); + end=(int) ((i + 1) * numPerThred + + left); + } else { + // 每个线程负责下载一定的numPerThred个字节 + start=(int) (i * numPerThred); + end=(int) ((i + 1) * numPerThred); + + } + new DownloadThread(conn, start, end,OUT_FILE_NAME,barrier).start(); + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + + } + + + + + } + + 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/group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloaderTest.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloaderTest.java new file mode 100644 index 0000000000..3c3957f933 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloaderTest.java @@ -0,0 +1,62 @@ +package com.m0312.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.m0312.download.api.ConnectionManager; +import com.m0312.download.api.DownloadListener; +import com.m0312.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://localhost:8080/test.jpg"; +// String url = "http://120.76.28.31/fileroot/pdf/test/testReport-20160803185703.pdf"; +// String url = "http://127.0.0.3:8082/testdownload.pdf"; + String url = "http://127.0.0.3:8082/applogo.png"; + + 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/group14/1091149131/2017JavaPro/src/com/m0312/download/LinkedListTest.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/LinkedListTest.java new file mode 100644 index 0000000000..b9796b2321 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/LinkedListTest.java @@ -0,0 +1,137 @@ +package com.m0312.download; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +import com.m0226.basic.Iterator; +import com.m0312.download.api.LinkedList; + +public class LinkedListTest { + + LinkedList list; + @Before + public void setUp() throws Exception { + list=new LinkedList(); + } + + public static void traverse(LinkedList list){ + Iterator ite=list.iterator(); + while(ite.hasNext()){ + System.out.print(ite.next()+","); + } + System.out.println("===end==="); + } + + @Test + public void testReverse() { + list.add(1); + list.add(2); + list.add(3); + list.add(4); + traverse(list); + list.reverse(); + traverse(list); + fail("Not yet implemented"); + } + + @Test + public void testRemoveFirstHalf() { + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + traverse(list); + list.removeFirstHalf(); + traverse(list); + fail("Not yet implemented"); + } + + @Test + public void testRemove() { + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + traverse(list); + list.remove(1,2);//145 + traverse(list); + fail("Not yet implemented"); + } + @Test + public void testRemoveIntInt() { + fail("Not yet implemented"); + } + + @Test + public void testGetElements() { + /* 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] */ + list.add(0); + list.add(1); + list.add(222); + list.add(3); + list.add(444); + list.add(5); +// traverse(list); + LinkedList listindex=new LinkedList(); + listindex.add(2); + listindex.add(4); + int[] result=list.getElements(listindex);//0135 + for (int i : result) { + System.out.println(i); + } + + + fail("Not yet implemented"); + } + + @Test + public void testSubtract() { + list.add(0); + list.add(1); + list.add(222); + list.add(222); + list.add(3); + list.add(444); + list.add(5); + traverse(list); + LinkedList listindex=new LinkedList(); + listindex.add(222); + listindex.add(5); + list.subtract(listindex); + traverse(list); + fail("Not yet implemented"); + } + + @Test + public void testRemoveDuplicateValues() { + list.add(0); + list.add(1); + list.add(22); + list.add(22); + list.add(44); + list.add(5); + list.add(6); + traverse(list); + list.removeDuplicateValues(); + traverse(list); + System.out.println("size : "+list.size()); + fail("Not yet implemented"); + } + + @Test + public void testRemoveRange() { + fail("Not yet implemented"); + } + + @Test + public void testIntersection() { + fail("Not yet implemented"); + } + +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/api/Connection.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/Connection.java new file mode 100644 index 0000000000..c2d347e6f4 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/Connection.java @@ -0,0 +1,27 @@ +package com.m0312.download.api; + +import java.io.IOException; +import java.net.URLConnection; + +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(); + public void setUrlCon(URLConnection urlCon); + public URLConnection getUrlCon(); +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionException.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionException.java new file mode 100644 index 0000000000..2b840892e4 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.m0312.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionManager.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionManager.java new file mode 100644 index 0000000000..00a19497b4 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.m0312.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/api/DownloadListener.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/DownloadListener.java new file mode 100644 index 0000000000..0eadca2622 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.m0312.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/api/LinkedList.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/LinkedList.java new file mode 100644 index 0000000000..9b396349a3 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/api/LinkedList.java @@ -0,0 +1,361 @@ +package com.m0312.download.api; +import java.util.NoSuchElementException; +import java.util.Objects; + +import com.m0226.basic.ArrayList; +import com.m0226.basic.Iterator; +import com.m0226.basic.List; + +public class LinkedList implements List { + + private Node head; + private int size = 0; + /** + * 与addLast()是一样的 + */ + public void add(Object o){ + addLast(o); + } + public void add(int index , Object o){ + if(index<0||index>size){ + throw new IndexOutOfBoundsException("Joy Index "+index+", Size: "+size); + } + Node prevNode=head; + Node curNode=head.next; + int count=0; + while(count<=index){ + if(count==index){ + Node newNode=new Node(); + newNode.data=o; + + newNode.next=curNode; + prevNode.next=newNode; + size++; + break; + } + curNode=curNode.next; + prevNode=prevNode.next; + count++; + } + + + } + public Object get(int index){ + if(index<0||index>=size) + throw new IndexOutOfBoundsException("Joy Index "+index+", Size: "+size); + + Node curNode=head.next; + int count=0; + while(count<=index){ + if(count==index){ + return curNode.data; + } + curNode=curNode.next; + count++; + } + return null; + } + public Object remove(int index){ + if(index<0||index>=size) + throw new IndexOutOfBoundsException("Joy Index "+index+", Size: "+size); + Node prevNode=head; + Node curNode=head.next; + int count=0; + while(count<=index){ + if(count==index){ + prevNode.next=curNode.next; + Object object=curNode.data; + curNode.next=null; + curNode=null; + size--; + return object; + } + curNode=curNode.next; + prevNode=prevNode.next; + count++; + } + return null; + } + + public int size(){ + return size; + } + + public void addFirst(Object o){ + Node objNode=new Node(); + objNode.data=o; + if(head==null) head=new Node(); + objNode.next=head.next; + size++; + head.next=objNode; + } + public void addLast(Object o){ + Node objNode=new Node(); + objNode.data=o; + if(head==null) head=new Node(); + + //也可以用iterator迭代,先不用吧 + Node curNode=head; + while(curNode.next!=null){ + curNode=curNode.next; + } + objNode.next=curNode.next; + curNode.next=objNode; + size++; + + } + public Object removeFirst(){ + if(head==null||head.next==null) + throw new NoSuchElementException(); + Node delNode=head.next; + head.next=delNode.next; + size--; + return delNode.data; + } + public Object removeLast(){ + if(head==null||head.next==null) + throw new NoSuchElementException(); + Node prevNode=head; + Node curNode=head.next; + while(curNode!=null){ + if(curNode.next==null){//说明是尾节点 + prevNode.next=curNode.next; + size--; + return curNode.data; + } + curNode=curNode.next; + prevNode=prevNode.next; + } + return null; + } + public Iterator iterator(){ + return new Iterator() { + private Node cur=head!=null?head.next:head; + @Override + public Object next() { + if(cur==null){ + throw new NoSuchElementException(); + } + Object object=cur.data; + cur=cur.next; + return object; + } + + @Override + public boolean hasNext() { + if(cur==null){ + return false; + }else{ + return true; + } + + } + }; + } + + + private static class Node{ + Object data; + Node next; + + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Object[] objarr=new Object[size]; + Node temp=head!=null?head.next:null; + int count=0; + while(temp!=null){ + objarr[count]=temp.data; + temp=temp.next; + count++; + } + temp=head; + for(int j=objarr.length-1;j>=0;j--){ + Node node=new Node(); + node.data=objarr[j]; + temp.next=node; + temp=node; + } + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(head==null||head.next==null)return; + int delenum=size/2; + int i=0; + Node temp=null; + Node nextNode=head.next; + while(isize-1||i<0) + throw new IndexOutOfBoundsException("Joy Index: "+i+", Size: "+size); + //如果i之后不足length个元素,该怎么处理,抛出异常,还是仅将剩下的移除 + int j=0; + int deleLen=0;//记录删除的个数 + + Node temp=null; + Node nextNode=head.next; + Node preNode=head; + //将node指针移动到i + while(j101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + Iterator ite=list.iterator(); + int[] result=new int[list.size]; + int index; + int i=0; + while(ite.hasNext()){ + index=(int) ite.next(); + if(index>=size){ + throw new IndexOutOfBoundsException("Joy Index: "+index+", Size: "+size); + } + result[i]=(int) get(index); + i++; + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + Iterator ite=list.iterator(); + int index=-1; + while(ite.hasNext()){ + Object obj=ite.next(); + index=indexOf(obj); + while(index>=0){ + remove(index); + size--; + index=indexOf(obj);//防止当前链表有重复元素 + } + } + } + /** + * 返回该值的索引,如果存在 + * @param o + * 2017年3月11日 下午5:42:15 + * @Author Joy + */ + public int indexOf(Object o){ + if(head==null||head.next==null) return -1; + int index=0; + + if(o==null){ + for(Node temp=head.next;temp!=null;temp=temp.next){ + if(temp.data==null){ + return index; + } + index++; + } + }else{ + for(Node temp=head.next;temp!=null;temp=temp.next){ + if(o.equals(temp.data)){ + return index; + } + index++; + } + } + return -1; + } + + /** + * ????? + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(head==null||head.next==null) return; + //递增 + Node cur=head.next; + Node nextNode=null; + Node temp=null; + for( ;cur!=null;cur=cur.next){ + nextNode=cur.next; + while(Objects.equals(cur.data, nextNode.data)){ + temp=nextNode; + nextNode=nextNode.next; + temp.next=null; + temp=null; + size--; + } + cur.next=nextNode; + System.out.println(nextNode.data+"*** size:"+size+",cur.next :"); + } + System.out.println("size : "+size); + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于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; + } +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionImpl.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..a3228c80b9 --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionImpl.java @@ -0,0 +1,41 @@ +package com.m0312.download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLConnection; + +import com.m0312.download.api.Connection; + +public class ConnectionImpl implements Connection{ + URLConnection urlCon; + @Override + public byte[] read(int startPos, int endPos) throws IOException { + byte[] buffer=new byte[endPos-startPos]; + InputStream is=urlCon.getInputStream(); + is.skip(startPos); + is.read(buffer, 0, endPos-startPos); + is.close(); + return buffer; + } + + @Override + public int getContentLength() { + return urlCon.getContentLength(); + } + + @Override + public void close() { + if(urlCon!=null){ + //??? + } + } + @Override + public URLConnection getUrlCon() { + return urlCon; + } + @Override + public void setUrlCon(URLConnection urlCon) { + this.urlCon = urlCon; + } + +} diff --git a/group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionManagerImpl.java b/group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..142b40f2ad --- /dev/null +++ b/group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,28 @@ +package com.m0312.download.impl; + +import java.io.File; +import java.net.URL; + +import com.m0312.download.api.Connection; +import com.m0312.download.api.ConnectionException; +import com.m0312.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + + @Override + public Connection open(String url) throws ConnectionException { + Connection con=new ConnectionImpl(); + + try { + URL website = new URL(url); + con.setUrlCon(website.openConnection());//urlcon是真正可以用的con连接 + + } catch (Exception e) { + } + + return con; + } + + +} diff --git a/group14/187114392/work_1_20170225/.classpath b/group14/187114392/homework/.classpath similarity index 100% rename from group14/187114392/work_1_20170225/.classpath rename to group14/187114392/homework/.classpath diff --git a/group14/187114392/homework/.gitignore b/group14/187114392/homework/.gitignore new file mode 100644 index 0000000000..a775f15365 --- /dev/null +++ b/group14/187114392/homework/.gitignore @@ -0,0 +1,3 @@ +bin/* +.idea/* +.settings/* diff --git a/group14/187114392/work_1_20170225/.project b/group14/187114392/homework/.project similarity index 100% rename from group14/187114392/work_1_20170225/.project rename to group14/187114392/homework/.project diff --git a/group14/187114392/work_1_20170225/ReadMe.md b/group14/187114392/homework/ReadMe.md similarity index 100% rename from group14/187114392/work_1_20170225/ReadMe.md rename to group14/187114392/homework/ReadMe.md diff --git a/group14/187114392/work_1_20170225/src/Main.java b/group14/187114392/homework/src/Main.java similarity index 100% rename from group14/187114392/work_1_20170225/src/Main.java rename to group14/187114392/homework/src/Main.java diff --git a/group14/187114392/homework/src/com/array/ArrayUtil.java b/group14/187114392/homework/src/com/array/ArrayUtil.java new file mode 100644 index 0000000000..e5ddb476a6 --- /dev/null +++ b/group14/187114392/homework/src/com/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/group14/187114392/homework/src/com/coderising/download/DownloadThread.java b/group14/187114392/homework/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..342b917a3f --- /dev/null +++ b/group14/187114392/homework/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,41 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CountDownLatch; + + +public class DownloadThread extends Thread{ + + Connection conn; + CountDownLatch latch; + String localpath; + RandomAccessFile raf; + int startPos; + int endPos; + + public DownloadThread(Connection conn, int startPos, int endPos, String localpath ,RandomAccessFile raf , CountDownLatch latch){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.latch = latch; + this.localpath = localpath; + this.raf = raf; + } + + public void run(){ + try { + RandomAccessFile raf = new RandomAccessFile(localpath,"rwd"); + byte[] slice_bytes = conn.read(startPos, endPos); + raf.seek(startPos); + raf.write(slice_bytes,0,slice_bytes.length); + raf.close(); + latch.countDown(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + } + } +} diff --git a/group14/187114392/homework/src/com/coderising/download/FileDownloader.java b/group14/187114392/homework/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..f79497f4e5 --- /dev/null +++ b/group14/187114392/homework/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,73 @@ +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; + + +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; + } + +} \ No newline at end of file diff --git a/group14/187114392/homework/src/com/coderising/download/FileDownloader_real.java b/group14/187114392/homework/src/com/coderising/download/FileDownloader_real.java new file mode 100644 index 0000000000..0ede039aeb --- /dev/null +++ b/group14/187114392/homework/src/com/coderising/download/FileDownloader_real.java @@ -0,0 +1,99 @@ +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 java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CountDownLatch; + + +public class FileDownloader_real { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + CountDownLatch latch; + + String localpath; + + int thread_count; + + public FileDownloader_real(String _url, int thread_count , String localpath , CountDownLatch latch) { + this.url = _url; + this.thread_count = thread_count; + this.latch = latch; + this.localpath = localpath; + } + + 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(); + System.out.printf("length is :%s \n" ,length); + int slice_size = length / thread_count; + RandomAccessFile raf = new RandomAccessFile(localpath,"rwd"); + raf.setLength(length); + raf.close(); + for (int i = 0; i < thread_count; i++) { + int start_pos = i * slice_size; + int end_pos = start_pos + slice_size - 1; + if (i == thread_count - 1) { + end_pos = length - 1; + } + Connection conn_t = cm.open(this.url); + new DownloadThread(conn_t,start_pos,end_pos,localpath,raf,latch).start(); + } + latch.await(); + } + catch (ConnectionException e) { + e.printStackTrace(); + } + catch (InterruptedException 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/group14/187114392/homework/src/com/coderising/download/api/Connection.java b/group14/187114392/homework/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group14/187114392/homework/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/group14/187114392/homework/src/com/coderising/download/api/ConnectionException.java b/group14/187114392/homework/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group14/187114392/homework/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group14/187114392/homework/src/com/coderising/download/api/ConnectionManager.java b/group14/187114392/homework/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group14/187114392/homework/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/group14/187114392/homework/src/com/coderising/download/api/DownloadListener.java b/group14/187114392/homework/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group14/187114392/homework/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/group14/187114392/homework/src/com/coderising/download/impl/ConnectionImpl.java b/group14/187114392/homework/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..dc27cee4f7 --- /dev/null +++ b/group14/187114392/homework/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,47 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + HttpURLConnection urlConnection = null; + + public ConnectionImpl(HttpURLConnection urlConnection) { + this.urlConnection = urlConnection; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + urlConnection.setRequestMethod("GET"); + urlConnection.setRequestProperty("Range","bytes=" + startPos + "-" + endPos); + urlConnection.setConnectTimeout(5000); + ByteArrayOutputStream buffer_array = new ByteArrayOutputStream(endPos - startPos); + if (urlConnection.getResponseCode() == 206) { + InputStream inputStream = urlConnection.getInputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) != -1) { + buffer_array.write(buffer,0,len); + } + System.out.printf("input stream ,startp :%s , endp:%s , result length is :%d \n",startPos,endPos,buffer_array.size()); + inputStream.close(); + buffer_array.close(); + } + urlConnection.disconnect(); + return buffer_array.toByteArray(); + } + + @Override + public int getContentLength() { + return urlConnection.getContentLength(); + } + + @Override + public void close() { + urlConnection.disconnect(); + } + +} diff --git a/group14/187114392/homework/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group14/187114392/homework/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..a3cba48a51 --- /dev/null +++ b/group14/187114392/homework/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,44 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.SystemDefaultCredentialsProvider; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { +// HttpGet request = new HttpGet(url); +// String result = ""; +// try { +// HttpResponse response = HttpClients.createDefault().execute(request); +// if(response.getStatusLine().getStatusCode()==200){ +// result = EntityUtils.toString(response.getEntity()); +// } +// System.out.println("result length is " + result.length()); +// } catch (IOException e) { +// e.printStackTrace(); +// } + ConnectionImpl conn_impl = null; + + try { + URL url_path = new URL(url); + HttpURLConnection urlconnection = (HttpURLConnection) url_path.openConnection(); + conn_impl = new ConnectionImpl(urlconnection); + } catch (IOException e) { + + } + return conn_impl; + } + +} diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/ArrayList.java b/group14/187114392/homework/src/com/coding/basic/ArrayList.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/ArrayList.java rename to group14/187114392/homework/src/com/coding/basic/ArrayList.java diff --git a/group14/187114392/homework/src/com/coding/basic/BinaryTreeNode.java b/group14/187114392/homework/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group14/187114392/homework/src/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/group14/187114392/homework/src/com/coding/basic/Iterator.java b/group14/187114392/homework/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..06ef6311b2 --- /dev/null +++ b/group14/187114392/homework/src/com/coding/basic/Iterator.java @@ -0,0 +1,7 @@ +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/LinkedList.java b/group14/187114392/homework/src/com/coding/basic/LinkedList.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/LinkedList.java rename to group14/187114392/homework/src/com/coding/basic/LinkedList.java diff --git a/group14/187114392/homework/src/com/coding/basic/List.java b/group14/187114392/homework/src/com/coding/basic/List.java new file mode 100644 index 0000000000..10d13b5832 --- /dev/null +++ b/group14/187114392/homework/src/com/coding/basic/List.java @@ -0,0 +1,9 @@ +package com.coding.basic; + +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/group14/187114392/work_1_20170225/src/com/coding/basic/Queue.java b/group14/187114392/homework/src/com/coding/basic/Queue.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/Queue.java rename to group14/187114392/homework/src/com/coding/basic/Queue.java diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/Stack.java b/group14/187114392/homework/src/com/coding/basic/Stack.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/Stack.java rename to group14/187114392/homework/src/com/coding/basic/Stack.java diff --git a/group14/187114392/work_1_20170225/test/ArrayList_Test.java b/group14/187114392/homework/test/ArrayList_Test.java similarity index 100% rename from group14/187114392/work_1_20170225/test/ArrayList_Test.java rename to group14/187114392/homework/test/ArrayList_Test.java diff --git a/group14/187114392/homework/test/FileDownloaderTest.java b/group14/187114392/homework/test/FileDownloaderTest.java new file mode 100644 index 0000000000..fa1263d487 --- /dev/null +++ b/group14/187114392/homework/test/FileDownloaderTest.java @@ -0,0 +1,107 @@ +import com.coderising.download.FileDownloader; +import com.coderising.download.FileDownloader_real; +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.ConnectionImpl; +import com.coderising.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import java.util.concurrent.CountDownLatch; +import java.io.IOException; + +public class FileDownloaderTest { + boolean downloadFinished = false; + int thread_count; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testFirstHttpGet() { + + String url = "http://127.0.0.1/test/climb.jpg"; + + ConnectionManager cm = new ConnectionManagerImpl(); + Connection conn = null; + try { + conn = cm.open(url); + Integer content_length = conn.getContentLength(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + } + + @Test + public void testDownload() { + thread_count = 10; +// String url = "http://localhost:8080/test.jpg"; + CountDownLatch latch = new CountDownLatch(thread_count); + + String url = "http://127.0.0.1/test/climb.jpg"; + String localpath = "G:\\Projects\\187114392\\haha.jpg"; + FileDownloader_real downloader = new FileDownloader_real(url,thread_count,localpath, latch); + + 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("下载完成!"); + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testIdeaJarDownload2() { + thread_count = 9; + CountDownLatch latch = new CountDownLatch(thread_count); + + String filename = "idea.jar"; + String url = "http://127.0.0.1/test/" + filename; + String localpath = "G:\\Projects\\187114392\\" + filename; + FileDownloader_real downloader = new FileDownloader_real(url,thread_count,localpath, latch); + ConnectionManager cm = new ConnectionManagerImpl(); + + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + downloader.execute(); + System.out.println("下载完成!"); + } + + + +} diff --git a/group14/187114392/work_1_20170225/test/LinkedList_Test.java b/group14/187114392/homework/test/LinkedList_Test.java similarity index 100% rename from group14/187114392/work_1_20170225/test/LinkedList_Test.java rename to group14/187114392/homework/test/LinkedList_Test.java diff --git a/group14/187114392/work_1_20170225/test/Queue_Test.java b/group14/187114392/homework/test/Queue_Test.java similarity index 100% rename from group14/187114392/work_1_20170225/test/Queue_Test.java rename to group14/187114392/homework/test/Queue_Test.java diff --git a/group14/187114392/work_1_20170225/test/Stack_Test.java b/group14/187114392/homework/test/Stack_Test.java similarity index 100% rename from group14/187114392/work_1_20170225/test/Stack_Test.java rename to group14/187114392/homework/test/Stack_Test.java diff --git a/group14/187114392/work_1_20170225/.idea/.name b/group14/187114392/work_1_20170225/.idea/.name deleted file mode 100644 index 9769cfad31..0000000000 --- a/group14/187114392/work_1_20170225/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -2017Learning \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/compiler.xml b/group14/187114392/work_1_20170225/.idea/compiler.xml deleted file mode 100644 index 96cc43efa6..0000000000 --- a/group14/187114392/work_1_20170225/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/copyright/profiles_settings.xml b/group14/187114392/work_1_20170225/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3377..0000000000 --- a/group14/187114392/work_1_20170225/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/encodings.xml b/group14/187114392/work_1_20170225/.idea/encodings.xml deleted file mode 100644 index 97626ba454..0000000000 --- a/group14/187114392/work_1_20170225/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/junitgenerator-prj-settings.xml b/group14/187114392/work_1_20170225/.idea/junitgenerator-prj-settings.xml deleted file mode 100644 index b6bb9db746..0000000000 --- a/group14/187114392/work_1_20170225/.idea/junitgenerator-prj-settings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/misc.xml b/group14/187114392/work_1_20170225/.idea/misc.xml deleted file mode 100644 index 6a48f33378..0000000000 --- a/group14/187114392/work_1_20170225/.idea/misc.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/modules.xml b/group14/187114392/work_1_20170225/.idea/modules.xml deleted file mode 100644 index f37bb20093..0000000000 --- a/group14/187114392/work_1_20170225/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/uiDesigner.xml b/group14/187114392/work_1_20170225/.idea/uiDesigner.xml deleted file mode 100644 index e96534fb27..0000000000 --- a/group14/187114392/work_1_20170225/.idea/uiDesigner.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/work_1_20170225.iml b/group14/187114392/work_1_20170225/.idea/work_1_20170225.iml deleted file mode 100644 index d6ebd48059..0000000000 --- a/group14/187114392/work_1_20170225/.idea/work_1_20170225.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.idea/workspace.xml b/group14/187114392/work_1_20170225/.idea/workspace.xml deleted file mode 100644 index 8c5615cc95..0000000000 --- a/group14/187114392/work_1_20170225/.idea/workspace.xml +++ /dev/null @@ -1,1295 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1488028819234 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group14/187114392/work_1_20170225/.settings/org.eclipse.jdt.core.prefs b/group14/187114392/work_1_20170225/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 3a21537071..0000000000 --- a/group14/187114392/work_1_20170225/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/group14/598808350/2017project/src/com/coderising/download/DownloadThread.java b/group14/598808350/2017project/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..d17f1a9a0c --- /dev/null +++ b/group14/598808350/2017project/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,40 @@ +package com.coderising.download; + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String localFile; + CyclicBarrier barrier; + + public DownloadThread( Connection conn, int startPos, int endPos,String localFile,CyclicBarrier barrier){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + public void run(){ + try{ + System.out.println("begin to read ["+startPos+"-"+endPos+"]"); + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile,"rw"); + file.seek(startPos); + file.write(data); + + file.close(); + conn.close(); + barrier.await(); + + }catch(Exception e){ + e.printStackTrace(); + } + } +} diff --git a/group14/598808350/2017project/src/com/coderising/download/FileDownloader.java b/group14/598808350/2017project/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c3e8124f0b --- /dev/null +++ b/group14/598808350/2017project/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,127 @@ +package com.coderising.download; + +import java.io.RandomAccessFile; +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 { + + private String url; + + private String localFile; + + DownloadListener listener; + + ConnectionManager cm; + + private static final int DOWNLOAD_TRHEAD_NUM = 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(DOWNLOAD_TRHEAD_NUM,new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }); + + + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + createPlaceHolderFile(this.localFile,length); + + int[][] rangs = allocateDownloadRange(DOWNLOAD_TRHEAD_NUM,length); + for(int i=0;i totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + URLConnection conn = null; + try { + conn = url.openConnection(); + return conn.getContentLength(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + + } + +} diff --git a/group14/598808350/2017project/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group14/598808350/2017project/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..0ebb1aad18 --- /dev/null +++ b/group14/598808350/2017project/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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 urlStr) throws ConnectionException { + return new ConnectionImpl(urlStr); + } + +} diff --git a/group14/598808350/2017project/src/com/coderising/linkedlist/LinkedList.java b/group14/598808350/2017project/src/com/coderising/linkedlist/LinkedList.java new file mode 100644 index 0000000000..ce395d359d --- /dev/null +++ b/group14/598808350/2017project/src/com/coderising/linkedlist/LinkedList.java @@ -0,0 +1,330 @@ +package com.coderising.linkedlist; + +import java.util.Stack; + +public class LinkedList { + + private Node head; + private int size; + + public LinkedList(){ + this.head = new Node(null,null); + } + public void add(Object o){ + Node lastNode = head; + for(int i=0;i7->10 , ���ú��Ϊ 10->7->3 + */ + public void reverse(){ + Stack nodes = new Stack(); + + Node currentNode = head; + while(currentNode != null){ + nodes.push(currentNode); + Node nextNode = currentNode.next; + currentNode.next = null; + currentNode = nextNode; + } + head = nodes.pop(); + currentNode = head; + + while(!nodes.isEmpty()){ + Node nextNode = nodes.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 l = size/2; + for(int i=0;i s){ + stNode = node.next; + s++; + } + return stNode; + } + + /** + * �ٶ���ǰ�����list������������е����� + * �ӵ�ǰ������ȡ����Щlist��ָ����Ԫ�� + * ���統ǰ���� = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * ���صĽ��Ӧ����[101,301,401,601] + * @param list + */ + public static int[] getElements(LinkedList list,Integer[] listB){ + int [] result = new int[list.size()]; + int res_index = 0; + for(int i=0;i min){ + start = index; + } + if((int)node.data < max){ + end = index; + break; + } + node = node.next; + index++; + } + + for(int i=start;i 0) { + hasRead = hasRead + len; + } + return bytes; + } + + @Override + public int getContentLength() { + return httpURLConnection.getContentLength(); + } + + @Override + public void close() { + try { + if (inputstream != null) + inputstream.close(); + httpURLConnection.disconnect(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public String getFileName() { + int index; + String fileName = "src/com/coderising/download/"; + String temp = httpURLConnection.getHeaderField("Content-Disposition"); + if (temp != null) { + index = temp.indexOf("="); + fileName += temp.substring(index + 2, temp.length() - 1); + return fileName; + } else { + index = url.lastIndexOf("/"); + fileName += url.substring(index + 1); + return fileName; + } + } + +} \ No newline at end of file diff --git a/group16/1012075117/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group16/1012075117/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..e95076a329 --- /dev/null +++ b/group16/1012075117/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,38 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +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 { + URL netURL = null; + URLConnection urlConnection = null; + HttpURLConnection httpURLConnection = null; + ConnectionImpl connectionImpl = null; + + try { + netURL = new URL(url); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + try { + urlConnection = netURL.openConnection(); + httpURLConnection = (HttpURLConnection) urlConnection; + httpURLConnection.connect(); + connectionImpl = new ConnectionImpl(httpURLConnection, url); + } catch (IOException e) { + e.printStackTrace(); + } + return connectionImpl; + } + +} \ No newline at end of file diff --git a/group16/1012075117/src/com/coderising/litestruts/LoginAction.java b/group16/1012075117/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..641e224b67 --- /dev/null +++ b/group16/1012075117/src/com/coderising/litestruts/LoginAction.java @@ -0,0 +1,34 @@ +package com.coderising.litestruts; + +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 diff --git a/group16/1012075117/src/com/coderising/litestruts/Struts.java b/group16/1012075117/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..ca1fa4892e --- /dev/null +++ b/group16/1012075117/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,182 @@ +package com.coderising.litestruts; + +import java.io.File; +import java.lang.reflect.Constructor; +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 java.util.Set; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +/** + * 读取配置文件 struts.xml - 第二次作业 + * @author stackwei + * @date 2017/3/20 + * @status ok + */ +public class Struts { + public static View runAction(String actionName, Map parameters) throws Exception { + + /* + * + * 0. 读取配置文件struts.xml + * + * 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , + * "password"="1234") , 那就应该调用 setName和setPassword方法 + * + * 2. 通过反射调用对象的execute 方法, 并获得返回值,例如"success" + * + * 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如 + * {"message": "登录成功"} , 放到View对象的parameters + * + * 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + * 放到View对象的jsp字段中。 + * + */ + + int flag = 0; + String className; + String executeResult; + String jsp; + Element resultElement; + List actionList = new ArrayList<>(); + Map classNameMap = new HashMap(); + Map messagesMap = new HashMap(); + View view = new View(); + + actionList = getRootElement("src/com/litestruts/struts.xml");// 获取所有节点 + classNameMap = getClassName(actionList, actionName, classNameMap);// 获取action的类名并放到Map中 + + className = (String) classNameMap.get("className"); + messagesMap = getResult(className, parameters);// messages包含了,调用execute()后的返回值result,和所有getter方法的值和属性 + + executeResult = (String) messagesMap.get("result"); + messagesMap.remove("result"); + flag = (int) classNameMap.get("flag"); + resultElement = actionList.get(flag); + jsp = getJSP(executeResult, resultElement);// 获取到里的jsp + + view.setJsp(jsp); + view.setParameters(messagesMap); + + return view; + } + + /** + * 获取所有节点 + * + * @param fileName + * @return + */ + private static List getRootElement(String fileName) { + File inputXml = new File(fileName); + SAXReader saxReader = new SAXReader(); + Document document = null; + try { + document = saxReader.read(inputXml); + } catch (DocumentException e) { + e.printStackTrace(); + } + Element root = document.getRootElement(); + List al = new ArrayList(); + for (Iterator i = root.elementIterator(); i.hasNext();) { // 获取所有action节点 + Element action = (Element) i.next(); + al.add(action); + } + return al; + } + + /** + * 根据给定的actionName,获取对应的class名字 + * + * @param al + * @param actionName + * @param map + * @return + */ + private static Map getClassName(List al, String actionName, Map map) { + String className = null; + for(int i=0;i getResult(String className, Map parameters) throws Exception { + Class actionClass = null; + Constructor constructor = null; + Object object = null; + Method method = null; + Map map = new HashMap(); + try { + actionClass = Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + try { + constructor = actionClass.getConstructor(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } + object = constructor.newInstance(); + Set keySet = parameters.keySet(); + // 据parameters中的数据,调用对象的setter方法 + for (String key : keySet) { + if (key.equals("name")) { + method = actionClass.getMethod("setName", String.class); + method.invoke(object, parameters.get(key)); + } + if (key.equals("password")) { + method = actionClass.getMethod("setPassword", String.class); + method.invoke(object, parameters.get(key)); + } + } + // 通过反射调用对象的execute 方法,并获得返回值,例如"success" + method = actionClass.getMethod("execute"); + String result = (String) method.invoke(object); + map.put("result", result); + + //找到对象的所有getter方法,把值和属性形成一个HashMap + Method getName = actionClass.getMethod("getName"); + Method getPassword = actionClass.getMethod("getPassword"); + Method getMessage = actionClass.getMethod("getMessage"); + map.put("name", getName.invoke(object)); + map.put("password", getPassword.invoke(object)); + map.put("message", getMessage.invoke(object)); + + return map; + } + + private static String getJSP(String result, Element actionElement) { + String jsp = null; + for (Iterator i = actionElement.elementIterator(); i.hasNext();) { // 获取所有action子节点result + Element resultElement = (Element) i.next(); + if(resultElement.attribute("name").getValue().equals(result)) { + jsp = resultElement.getTextTrim(); + } + } + return jsp; + } + +} \ No newline at end of file diff --git a/group16/1012075117/src/com/coderising/litestruts/StrutsTest.java b/group16/1012075117/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..4e1ced3ee5 --- /dev/null +++ b/group16/1012075117/src/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,39 @@ +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() throws Exception { + + 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 Exception { + 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")); + } + +} \ No newline at end of file diff --git a/group16/1012075117/src/com/coderising/litestruts/View.java b/group16/1012075117/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..564b4127e1 --- /dev/null +++ b/group16/1012075117/src/com/coderising/litestruts/View.java @@ -0,0 +1,26 @@ +package com.coderising.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; + } +} \ No newline at end of file diff --git a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/ArrayList.java b/group16/1012075117/src/com/coding/basic/ArrayList.java similarity index 94% rename from group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/ArrayList.java rename to group16/1012075117/src/com/coding/basic/ArrayList.java index a1d46a21d8..6a83a34b41 100644 --- a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/ArrayList.java +++ b/group16/1012075117/src/com/coding/basic/ArrayList.java @@ -1,9 +1,10 @@ -package com.stackwei.DataStructure; +package com.coding.basic; /** - * - * @author stackwei -2017.2.25 - * + * 实现 ArrayList - 第一次作业 + * @author stackwei + * @date 2017/2/25 + * @status ok */ public class ArrayList implements List { diff --git a/group16/1012075117/src/com/coding/basic/Iterator.java b/group16/1012075117/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..e7cbd474ec --- /dev/null +++ b/group16/1012075117/src/com/coding/basic/Iterator.java @@ -0,0 +1,6 @@ +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); +} diff --git a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/LinkedList.java b/group16/1012075117/src/com/coding/basic/LinkedList.java similarity index 96% rename from group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/LinkedList.java rename to group16/1012075117/src/com/coding/basic/LinkedList.java index a1c728f0a1..fd0214bd1a 100644 --- a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/LinkedList.java +++ b/group16/1012075117/src/com/coding/basic/LinkedList.java @@ -1,9 +1,10 @@ -package com.stackwei.DataStructure; +package com.coding.basic; /** - * - * @author stackwei -2017.2.25 - * + * 实现 LinkedList - 第一次作业 + * @author stackwei + * @date 2017/2/25 + * @status ok */ public class LinkedList implements List { diff --git a/group16/1012075117/src/com/coding/basic/List.java b/group16/1012075117/src/com/coding/basic/List.java new file mode 100644 index 0000000000..03fa879b2e --- /dev/null +++ b/group16/1012075117/src/com/coding/basic/List.java @@ -0,0 +1,13 @@ +package com.coding.basic; + +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/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/Queue.java b/group16/1012075117/src/com/coding/basic/Queue.java similarity index 85% rename from group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/Queue.java rename to group16/1012075117/src/com/coding/basic/Queue.java index 4a227495e9..41cd854e34 100644 --- a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/Queue.java +++ b/group16/1012075117/src/com/coding/basic/Queue.java @@ -1,9 +1,10 @@ -package com.stackwei.DataStructure; +package com.coding.basic; /** - * - * @author stackwei -2017.2.25 - * + * 实现 Queue - 第一次作业 + * @author stackwei + * @date 2017/2/25 + * @status ok */ public class Queue { diff --git a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/Stack.java b/group16/1012075117/src/com/coding/basic/Stack.java similarity index 85% rename from group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/Stack.java rename to group16/1012075117/src/com/coding/basic/Stack.java index 1b047ffafd..34d4692113 100644 --- a/group16/1012075117/DataStructure219/src/com/stackwei/DataStructure/Stack.java +++ b/group16/1012075117/src/com/coding/basic/Stack.java @@ -1,9 +1,10 @@ -package com.stackwei.DataStructure; +package com.coding.basic; /** - * - * @author stackwei -2017.2.25 - * + * 实现 Stack - 第一次作业 + * @author stackwei + * @date 2017/2/25 + * @status ok */ public class Stack { diff --git a/group16/1012075117/src/com/coding/basic/array/ArrayUtil.java b/group16/1012075117/src/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..f75a0be1eb --- /dev/null +++ b/group16/1012075117/src/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,263 @@ +package com.coding.basic.array; + +import java.util.Arrays; + +/** + * 数组工具类-第二次作业 + * @author stackwei + * @date 2017/3/20 + * @status ok + */ +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 length; + int[] temp; + + length = origin.length; + temp = new int[length]; + for (int i = 0; i < length; i++) { + temp[length - i - 1] = origin[i]; + } + for (int i = 0; i < length; i++) { + origin[i] = temp[i]; + } + } + + /** + * 现在有如下的一个数组: 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) { + int flag = 0; + int j = 0; + int length; + length = oldArray.length; + int[] newArray; + + for (int i = 0; i < length; i++) { + if (oldArray[i] != 0) { + flag++; + } + } + newArray = new int[flag]; + for (int i = 0; i < length; i++) { + if (oldArray[i] != 0) { + newArray[j] = oldArray[i]; + j++; + } + } + return newArray; + } + + /** + * 给定两个已经排序好的整形数组, 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) { + int[] temp; + int[] array3; + int flag = 0; + int repeat = 0; + boolean boolea = true; + int length1 = array1.length; + int length2 = array2.length; + temp = new int[length1 + length2]; + + // 先把a1添加到temp + for (int i = 0; i < length1; i++) { + temp[i] = array1[i]; + } + // 把a2中不重复的添加到temp + for (int i = 0; i < length2; i++) { + for (int j = 0; j < length1; j++) { + if (temp[j] == array2[i]) { + boolea = false; + repeat++; + } + } + if (boolea) { + temp[length1 + flag] = array2[i]; + flag++; + } + boolea = true; + } + // 有重复就new一个数组长度减去重复的长度的a3,排序并返回 + if (repeat != 0) { + array3 = new int[length1 + length2 - repeat]; + for (int i = 0; i < (temp.length - repeat); i++) { + array3[i] = temp[i]; + } + Arrays.sort(array3); + return array3; + } + // 无重复就排序并返回 + Arrays.sort(temp); + return temp; + } + + /** + * 把一个已经存满数据的数组 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) { + int[] temp; + int length; + + length = oldArray.length; + temp = new int[length + size]; + for (int i = 0; i < length; i++) { + temp[i] = oldArray[i]; + } + oldArray = null; + oldArray = temp; + + return oldArray; + } + + /** + * 斐波那契数列为: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) { + int[] temp = new int[2]; + int[] array; + int f1 = 1; + int f2 = 1; + int length = 2; + + if (max <= 1) { + return null; + } + + temp[0] = f1; + temp[1] = f2; + if (max == 2) { + return temp; + } + + for (int i = 2; temp[i - 1] < max; i++) { + if ((f1 + f2) >= max) + break; + if (i + 1 > temp.length) { + temp = new ArrayUtil().grow(temp, 1); + } + temp[i] = f1 + f2; + f1 = temp[i - 1]; + f2 = temp[i]; + length++; + } + array = new int[length]; + for (int i = 0; i < length; i++) { + array[i] = temp[i]; + } + + return array; + } + + /** + * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * + * @param max + * @return + */ + public int[] getPrimes(int max) { + int[] temp = new int[1]; + boolean flag = true; + int i = 0; + + if (max < 3) + return null; + + for (int j = 2; j < max; j++) { + for (int k = 2; k <= Math.sqrt(j); k++) { + if (j % k == 0) { + flag = false; + break; + } + } + if (flag) { + if (i + 1 > temp.length) + temp = new ArrayUtil().grow(temp, 1); + temp[i] = j; + i++; + } + flag = true; + } + return temp; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * + * @param max + * @return + */ + public int[] getPerfectNumbers(int max) { + int[] temp = new int[1]; + int i = 0; + + if (max < 6) + return null; + + for (int j = 1; j < max; j++) { + int total = 0; + for (int k = 1; k < j / 2 + 1; k++) { + if (j % k == 0) + total += k; + } + if (total == j) { + if (i + 1 > temp.length) + temp = new ArrayUtil().grow(temp, 1); + temp[i] = j; + i++; + } + } + return temp; + } + + /** + * 用seperator 把数组 array给连接起来 例如array= [3,8,9], seperator = "-" 则返回值为"3-8-9" + * + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator) { + if(array == null || array.length ==0 || seperator == null) + return null; + + StringBuilder sb = new StringBuilder(); + int length = array.length; + for(int i=0;i7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int 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) { + 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; + } + +} \ No newline at end of file diff --git a/group16/2562124714/.idea/misc.xml b/group16/2562124714/.idea/misc.xml index e97ef03f44..05483570e0 100644 --- a/group16/2562124714/.idea/misc.xml +++ b/group16/2562124714/.idea/misc.xml @@ -1,22 +1,6 @@ - + - - - - - 1.7 - - - - - - - \ No newline at end of file diff --git a/group16/2562124714/.idea/workspace.xml b/group16/2562124714/.idea/workspace.xml index d357c0f9a1..bba44e297b 100644 --- a/group16/2562124714/.idea/workspace.xml +++ b/group16/2562124714/.idea/workspace.xml @@ -13,49 +13,60 @@ + + + + + - - - - - - - - - - - + - - - - + + + + + + + + + + + + - + - - - + + + + + - - + + - - + + @@ -63,46 +74,78 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -130,8 +173,6 @@ + + + + true + DEFINITION_ORDER + @@ -166,6 +216,7 @@ + @@ -209,20 +260,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + @@ -410,6 +521,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -468,6 +717,15 @@ + + + + + + + + + + + + + + + @@ -529,6 +793,22 @@ + + + + + + + + + + + + + + + + @@ -557,6 +837,8 @@ @@ -568,40 +850,56 @@ + + + + + + + + + + + - + - - + - + + - + + + + @@ -616,66 +914,269 @@ + + + + + + + + + + + + + - - + + - - - - + + + + + + - + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + - + - - + + - - + + + + - + - - + + - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -683,7 +1184,6 @@ - @@ -699,82 +1199,182 @@ - - - - - + + + + + + + - + - + + + - + - + + + - - + + + + + + + - - + + + + + + + - + - - - - + + + + + + + + + + + + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.8 + + + + + + \ No newline at end of file diff --git a/group16/2562124714/src/Test/StrutsTest.java b/group16/2562124714/src/Test/StrutsTest.java new file mode 100644 index 0000000000..663c9dba3b --- /dev/null +++ b/group16/2562124714/src/Test/StrutsTest.java @@ -0,0 +1,43 @@ +package Test; + +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"); + + + com.coderising.litestruts.View view = com.coderising.litestruts.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"); //密码和预设的不一致 + + com.coderising.litestruts.View view = com.coderising.litestruts.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/group16/2562124714/src/Test/TestRunner.java b/group16/2562124714/src/Test/TestRunner.java index 2bf465f832..963fb955d3 100644 --- a/group16/2562124714/src/Test/TestRunner.java +++ b/group16/2562124714/src/Test/TestRunner.java @@ -10,7 +10,7 @@ */ public class TestRunner { public static void main(String[] args) { - org.junit.runner.Result result = JUnitCore.runClasses(BinaryTreeNodeTest.class); + org.junit.runner.Result result = JUnitCore.runClasses(StrutsTest.class); for (Failure failure:result.getFailures()) { System.out.println(failure.toString()); } diff --git a/group16/2562124714/src/com/coderising/action/LoginAction.java b/group16/2562124714/src/com/coderising/action/LoginAction.java new file mode 100644 index 0000000000..8f1ea73abb --- /dev/null +++ b/group16/2562124714/src/com/coderising/action/LoginAction.java @@ -0,0 +1,41 @@ +package com.coderising.action; + +/** + * Created by zhangwj on 2017/3/9. + */ +public class LoginAction { + private String Name; + private String Password; + private String Message; + + public void setName(String name) + { + this.Name = name; + } + public void setPassword(String pass) + { + this.Password = pass; + } + + public String exectue() + { + if (this.Name == "test" && this.Password == "1234") + { + this.Message = "login successful"; + return "success"; + } + else + { + this.Message = "login failed,please check your user/pwd"; + return "fail"; + } + } + + public String getMessage() + { + return this.Message; + } + + + +} diff --git a/group16/2562124714/src/com/coderising/array/ArrayUtil.java b/group16/2562124714/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..4b496a41f7 --- /dev/null +++ b/group16/2562124714/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,292 @@ +package com.coderising.array; + +import com.*; + +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){ + if (1 == origin.length || 0 == origin.length) + { + return; + } + + int temp = 0; + 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 Integer[] removeZero(int[] oldArray){ + com.coding.basic.ArrayList blist = new com.coding.basic.ArrayList(); + + //int j = 0; + + for(int i = 0; i < oldArray.length; i++) + { + if (0 != oldArray[i]) + { + blist.add(oldArray[i]); + } + } + + Object[] newArray = blist.ToArray(); + + return (Integer[])newArray; + } + + /** + * 给定两个已经排序好的整形数组, 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 Integer[] merge(int[] array1, int[] array2){ + com.coding.basic.ArrayList blist = new com.coding.basic.ArrayList(); + int i = 0; + + for (i = 0; i < array1.length; i++) + { + blist.add(array1[0]); + } + + for(i = 0; i < array2.length; i++) + { + for (int j = 0; j < blist.size(); j ++) + { + if (array2[i] >= (int)blist.get(j + 1)) + { + if (array2[i] == (int)blist.get(j + 1)) + { + break; + } + //已经到最后了 + if (j == blist.size() - 1) + { + if (array2[i] == (int)blist.get(j + 1)) + { + break; + } + else + { + blist.add(j + 1, array2[i]); + break; + } + } + else + { + if (array2[i] <= (int)blist.get(j + 2)) + { + if (array2[i] == (int)blist.get(j + 2)) + { + break; + } + else + { + blist.add(j + 1, array2[i]); + break; + } + } + } + + } + else + { + if (j == 0) + { + blist.add(j + 1, array2[i]); + break; + } + else + { + continue; + } + } + } + } + + return (Integer[]) blist.ToArray(); + } + /** + * 把一个已经存满数据的数组 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){ + int[] NewArray = new int[oldArray.length + size]; + + for(int i = 0; i < NewArray.length; i++) + { + if (i < oldArray.length) { + NewArray[i] = oldArray[i]; + } + else + { + NewArray[i] = 0; + } + } + + 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 Integer[] fibonacci(int max){ + com.coding.basic.ArrayList result = new com.coding.basic.ArrayList(); + int i = 0; + int TempMax = 0; + + + while (true) + { + TempMax = CaculateFibonacci(i++); + if (TempMax <= max) + { + result.add(TempMax); + continue; + } + else + { + break; + } + } + + return (Integer[])result.ToArray(); + } + + public int CaculateFibonacci(int i) + { + if (1 == i) + return 1; + else if (2 == i) + return 1; + else + return CaculateFibonacci(i - 1) + CaculateFibonacci(i - 2); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public Integer[] getPrimes(int max){ + com.coding.basic.ArrayList result = new com.coding.basic.ArrayList(); + + + + for(int i = 2; i < max; i ++) + { + if(CaculatePrimes(i)) + { + result.add(i); + } + } + + return (Integer[])result.ToArray(); + } + + //计算素数函数 算法好像不高明啊! + public boolean CaculatePrimes(int Num) + { + for (int i = 2; i < Math.sqrt(Num); i++) + { + if (Num % i == 0) + { + return false; + } + } + return true; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public Integer[] getPerfectNumbers(int max){ + com.coding.basic.ArrayList result = new com.coding.basic.ArrayList(); + + for (int i = 6; i < max; i++) + { + if (IsPerfectNumber(i)) + { + result.add(i); + } + } + return (Integer[])result.ToArray(); + } + + //计算所有的因子之和 算法并不高明啊! + public boolean IsPerfectNumber(int Num) + { + int temp = 0; + for (int i = 1; i < Num; i++) + { + if (Num % i == 0) + { + temp += i; + } + } + if (temp == Num) + { + return true; + } + else + { + return false; + } + } + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param + * @return + */ + public String join(int[] array, String seperator){ + String result = ""; + + for (int i = 0; i < array.length - 1; i++) + { + result += Integer.toString(array[i])+ seperator; + } + + result += Integer.toString(array[array.length]); + + + return result; + } + + +} diff --git a/group16/2562124714/src/com/coderising/download/DownloadThread.java b/group16/2562124714/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..b03ab73e24 --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,37 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CountDownLatch; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + CountDownLatch latch; + RandomAccessFile ResultFile; + + public DownloadThread( Connection conn, int startPos, int endPos, CountDownLatch latchArg, RandomAccessFile fileArg){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.latch = latchArg; + this.ResultFile = fileArg; + } + public void run(){ + try { + byte []b = this.conn.read(this.startPos, this.endPos); + System.out.println(b.toString()); + ResultFile.seek(startPos); + ResultFile.write(b, 0, endPos - startPos); + } catch (IOException e) { + e.printStackTrace(); + } + this.latch.countDown(); //下载完成就lockdown + } +} diff --git a/group16/2562124714/src/com/coderising/download/FileDownloader.java b/group16/2562124714/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..62a630867d --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,128 @@ +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 java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CountDownLatch; + + +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方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + //写入文件 + //得到文件名 + String fileName = "E:\\zhuomian\\java课程\\testFile.jpg"; + //根据文件大小及文件名,创建一个同样大小,同样文件名的文件 + File file = new File(fileName); + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(file, "rw"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + Connection conn1 = null; + try { + CountDownLatch countdownlatch = new CountDownLatch(3); + + conn1 = cm.open(this.url); + Connection conn4 = cm.open(this.url); + int length = conn4.getContentLength(); + try { + raf.setLength(length); //设置文件长度 一系列的占位符 + } catch (IOException e) { + e.printStackTrace(); + } + new DownloadThread(conn1, 0, length / 3 - 1, countdownlatch, raf).start(); + Connection conn2 = cm.open(this.url); + new DownloadThread(conn2, length / 3, (length / 3) *2 - 1, countdownlatch, raf).start(); + Connection conn3 = cm.open(this.url); + new DownloadThread(conn3, (length / 3) *2 , length - 1, countdownlatch, raf).start(); + + + try { + countdownlatch.await(); + this.listener.notifyFinished(); + conn4.close(); + conn1.close(); + conn2.close(); + conn3.close(); + try { + if (raf != null) { + raf.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + //this.listener.notifyFinished(); + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(conn1 != null){ + conn1.close(); + } + if (raf != null) + { + try { + raf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + + + } + + 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/group16/2562124714/src/com/coderising/download/FileDownloaderTest.java b/group16/2562124714/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..52d6495465 --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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://upload.qianlong.com/2017/0310/1489104335573.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/group16/2562124714/src/com/coderising/download/api/Connection.java b/group16/2562124714/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group16/2562124714/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/group16/2562124714/src/com/coderising/download/api/ConnectionException.java b/group16/2562124714/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group16/2562124714/src/com/coderising/download/api/ConnectionManager.java b/group16/2562124714/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..f657345633 --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + Connection open(String url) throws ConnectionException; +} diff --git a/group16/2562124714/src/com/coderising/download/api/DownloadListener.java b/group16/2562124714/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group16/2562124714/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/group16/2562124714/src/com/coderising/download/impl/ConnectionImpl.java b/group16/2562124714/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..8b4bee0010 --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,55 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.ProtocolException; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + private HttpURLConnection connection; + @Override + public byte[] read(int startPos, int endPos) throws IOException { + this.connection.setRequestMethod("GET"); + this.connection.setReadTimeout(5000); + this.connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream inputstream = this.connection.getInputStream(); + byte[]b = new byte[endPos - startPos + 10]; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + System.out.println("开始下载"+startPos+"-" + endPos +"---"); + int length; + while(-1 != (length = inputstream.read(b))) { + bos.write(b, 0 ,length); + } + + + return bos.toByteArray(); + } + + @Override + public int getContentLength() { + int fileSize = this.connection.getContentLength(); + + System.out.println("文件大小为:"+fileSize); + + return fileSize; + } + + @Override + public void close() { + this.connection.disconnect(); + + + } + + public ConnectionImpl(URLConnection urlconnection) + { + this.connection = (HttpURLConnection)urlconnection; + } + +} diff --git a/group16/2562124714/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group16/2562124714/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..b7b8e02de5 --- /dev/null +++ b/group16/2562124714/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,35 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String desiredUrl) throws ConnectionException { + URL url = null; + + try + { + //create the HttpURLConnection + url = new URL(desiredUrl); + URLConnection connection = url.openConnection(); + //connection.connect(); + ConnectionImpl connectionimpl = new ConnectionImpl(connection); + return connectionimpl; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + + //return null; + } + +} diff --git a/group16/2562124714/src/com/coderising/litestruts/Struts.java b/group16/2562124714/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..2bc79f1199 --- /dev/null +++ b/group16/2562124714/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,128 @@ +package com.coderising.litestruts; + +import com.sun.org.apache.regexp.internal.RE; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.helpers.DefaultHandler; + +import javax.print.Doc; +import org.w3c.dom.Document; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.File; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + + + +public class Struts { + + public static View runAction(String actionName, Map parameters) { + + //0. SAX Parser is faster and uses less memory than DOM parser. Dom解析功能强大,可增删改查,操作时会将xml文档以文档对象的方式读取到内存中,因此适用于小文档 + //Sax解析是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档 + + long lasting = System.currentTimeMillis(); + + try { + File f = new File("C:\\Users\\zhangwj\\Desktop\\java课程\\coding\\coding2017-1\\group16\\2562124714\\src\\com\\coderising\\litestruts\\struts.xml"); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(f); + NodeList nl = doc.getElementsByTagName("struts"); + for (int i = 0; i < nl.getLength(); i++) { + + Node node = doc.getElementsByTagName("action").item(i); //get action node + //System.out.print("action name is " + doc.getElementsByTagName("action").item(i).getFirstChild().getNodeValue()); + Element e = (Element) node; + System.out.printf("attribute of name is "+ e.getAttribute("name") + " actionName Need is" + actionName); + if (e.getAttribute("name").toString().equals(actionName)) { + //1 获取相应的class 设置用户名和密码 + // System.out.print("action name is " + e.getAttribute("name") + " action class is " + e.getAttribute("class")); + Class ActionClass = Class.forName(e.getAttribute("class")); + //强制类型转换 + Object Action = ActionClass.newInstance(); + for (Map.Entry entry : parameters.entrySet() + ) { + if (entry.getKey() == "name") { + //设置姓名 + //2 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + Method fun_setName = ActionClass.getDeclaredMethod("setName", String.class); + fun_setName.invoke(Action, entry.getValue()); + + } else if (entry.getKey() == "password") { + //设置密码 + Method fun_setName = ActionClass.getDeclaredMethod("setPassword", String.class); + fun_setName.invoke(Action, entry.getValue()); + } else { + continue; + } + } + + Method ExecuteMethod = ActionClass.getDeclaredMethod("exectue"); + //2 调用execute方法 + String ss = "11"; + Object ExecuteResultValue = ExecuteMethod.invoke(Action); + + //3通过反射找到对象的所有getter方法(例如 getMessage), + //通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + //放到View对象的parameters + Method Getter_Method = ActionClass.getDeclaredMethod("getMessage"); + Object message = Getter_Method.invoke(Action); + Map messageMap = new HashMap(); + messageMap.put("message", (String) message); + com.coderising.litestruts.View view = new com.coderising.litestruts.View(); + view.setParameters(messageMap); + + //4 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + //放到View对象的jsp字段中。 + //首先获取result节点 + NodeList ResultNL = ((Element) node).getElementsByTagName("result"); + for (int j = 0; j < ResultNL.getLength(); j++ + ) { + Node node1 = ResultNL.item(j); + Element e1 = (Element) node1; + System.out.println("name is " + e1.getAttribute("name") + "return Value is" + (String) ExecuteResultValue); + if (e1.getAttribute("name").toString().equals((String) ExecuteResultValue)) { + view.setJsp(node1.getFirstChild().getNodeValue()); + } + } + + return view; + + + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + /* + + 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/group16/2562124714/src/com/coderising/litestruts/View.java b/group16/2562124714/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group16/2562124714/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group16/2562124714/src/com/coderising/litestruts/struts.xml b/group16/2562124714/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..90cf18b7da --- /dev/null +++ b/group16/2562124714/src/com/coderising/litestruts/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/group16/2562124714/src/com/coding/basic/ArrayList.java b/group16/2562124714/src/com/coding/basic/ArrayList.java index f1d5a9fdd9..acdfadd83d 100644 --- a/group16/2562124714/src/com/coding/basic/ArrayList.java +++ b/group16/2562124714/src/com/coding/basic/ArrayList.java @@ -1,5 +1,7 @@ package com.coding.basic; +import java.util.Objects; + public class ArrayList implements List { private int size = 0; @@ -96,5 +98,22 @@ public int size(){ public Iterator iterator(){ return null; } + + public Object[] ToArray() + { + Object [] Array = new Object[this.size]; + if(this.size == 0) + { + return new Object[0]; + } + + //使用System.arraycopy()来复制数组是更优的办法 zwj 20170309 + for (int i = 0 ; i < this.size; i ++) + { + Array[i] = this.elementData[i]; + } + + return Array; + } } diff --git a/group16/2816977791/thirdExercise/src/DownloadThread.java b/group16/2816977791/thirdExercise/src/DownloadThread.java new file mode 100644 index 0000000000..9ff8ef6ebd --- /dev/null +++ b/group16/2816977791/thirdExercise/src/DownloadThread.java @@ -0,0 +1,34 @@ +import api.Connection; + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +public class DownloadThread extends Thread { + + Connection conn; + int startPos; + int endPos; + + private CyclicBarrier barrier; + + public DownloadThread(Connection conn, int startPos, int endPos, CyclicBarrier barrier) { + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.barrier = barrier; + } + + public void run() { + try { + byte[] buffer = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile("/Users/nvarchar/example.jpg", "rw"); + raf.seek(startPos); + raf.write(buffer); + raf.close(); + barrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group16/2816977791/thirdExercise/src/FileDownloader.java b/group16/2816977791/thirdExercise/src/FileDownloader.java new file mode 100644 index 0000000000..5dcc0da3e7 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/FileDownloader.java @@ -0,0 +1,74 @@ +import api.Connection; +import api.ConnectionException; +import api.ConnectionManager; +import api.DownloadListener; + +import java.util.concurrent.CyclicBarrier; + + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + private static final int THREAD_NUM = 10; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() { + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + CyclicBarrier barrier = new CyclicBarrier(THREAD_NUM, new Runnable() { + @Override + public void run() { + listener.notifyFinished(); + } + }); + Connection conn = null; + try { + //(1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + conn = cm.open(this.url); + + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + int length = conn.getContentLength(); + + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + int start = 0; + int endPos = 0; + for (int i = 0; i < THREAD_NUM; i++) { + endPos = start + length / THREAD_NUM; + System.out.println(start + "=====" + endPos); + new DownloadThread(conn, start, endPos > (length - 1) ? length - 1 : endPos, barrier).start(); + start = endPos + 1; + } + } 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/group16/2816977791/thirdExercise/src/FileDownloaderTest.java b/group16/2816977791/thirdExercise/src/FileDownloaderTest.java new file mode 100644 index 0000000000..f66d825322 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/FileDownloaderTest.java @@ -0,0 +1,57 @@ +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import api.ConnectionManager; +import api.DownloadListener; +import 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 = "https://cdn.pixabay.com/photo/2017/03/31/15/34/sunset-2191645_1280.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/group16/2816977791/thirdExercise/src/api/Connection.java b/group16/2816977791/thirdExercise/src/api/Connection.java new file mode 100644 index 0000000000..5b41847037 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/api/Connection.java @@ -0,0 +1,23 @@ +package 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/group16/2816977791/thirdExercise/src/api/ConnectionException.java b/group16/2816977791/thirdExercise/src/api/ConnectionException.java new file mode 100644 index 0000000000..755a5e8bfc --- /dev/null +++ b/group16/2816977791/thirdExercise/src/api/ConnectionException.java @@ -0,0 +1,5 @@ +package api; + +public class ConnectionException extends Exception { + +} diff --git a/group16/2816977791/thirdExercise/src/api/ConnectionManager.java b/group16/2816977791/thirdExercise/src/api/ConnectionManager.java new file mode 100644 index 0000000000..b57947e239 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group16/2816977791/thirdExercise/src/api/DownloadListener.java b/group16/2816977791/thirdExercise/src/api/DownloadListener.java new file mode 100644 index 0000000000..e652867321 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/api/DownloadListener.java @@ -0,0 +1,5 @@ +package api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group16/2816977791/thirdExercise/src/basic/Iterator.java b/group16/2816977791/thirdExercise/src/basic/Iterator.java new file mode 100644 index 0000000000..9570e2792d --- /dev/null +++ b/group16/2816977791/thirdExercise/src/basic/Iterator.java @@ -0,0 +1,11 @@ +package basic; + +/** + * @author nvarchar + * date 2017/3/27 + */ +public interface Iterator { + boolean hasNext(); + + Object next(); +} diff --git a/group16/2816977791/thirdExercise/src/basic/LinkedList.java b/group16/2816977791/thirdExercise/src/basic/LinkedList.java new file mode 100644 index 0000000000..742ed954ba --- /dev/null +++ b/group16/2816977791/thirdExercise/src/basic/LinkedList.java @@ -0,0 +1,378 @@ +package basic; + +import java.util.NoSuchElementException; + +/** + * @author nvarchar + * date 2017/3/27 + */ +public class LinkedList implements List { + + private Node head; + private Node tail; + private int size; + + public void add(Object o) { + addLast(o); + } + + public void add(int index, Object o) { + checkPositionIndex(index); + if (index == size) { + addLast(o); + } else if (index == 0) { + addFirst(o); + } else { + Node node = node(index - 1); + Node newNode = new Node(o, node.next); + node.next = newNode; + size++; + } + } + + public Object get(int index) { + checkPositionIndex(index); + return node(index).data; + } + + public Object remove(int index) { + checkPositionIndex(index); + if (index == 0) { + return removeFirst(); + } else if (index == size - 1) { + return removeLast(); + } else { + Node newNode = node(index); + Node prevNode = node(index - 1); + prevNode.next = newNode.next; + size--; + return newNode.data; + } + } + + public int size() { + return size; + } + + public void addFirst(Object o) { + Node first = head; + Node newNode = new Node(o, first); + head = newNode; + if (first == null) { + tail = newNode; + } + size++; + } + + public void addLast(Object o) { + Node newNode = new Node(o, null); + Node last = tail; + tail = newNode; + if (last == null) { + head = newNode; + } else { + last.next = newNode; + } + size++; + } + + public Object removeFirst() { + Node first = head; + if (first == null) { + throw new NoSuchElementException(); + } else { + Node next = first.next; + if (next == null) { + head = null; + tail = null; + } else { + head = next; + } + size--; + return first.data; + } + } + + public Object removeLast() { + Node last = tail; + if (last == null) { + throw new NoSuchElementException(); + } else { + if (size == 1) { + head = null; + tail = null; + } else { + tail = node(size - 2); + tail.next = null; + } + size--; + return last.data; + } + } + + public Iterator iterator() { + return new Iterator() { + private int nextIndex; + private Node node; + + @Override + public boolean hasNext() { + return nextIndex < size; + } + + @Override + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } else { + nextIndex++; + if (node == null) { + node = head; + return node.data; + } else { + node = node.next; + return node.data; + } + } + } + }; + } + + private void checkPositionIndex(int index) { + if (!isPositionIndex(index)) { + throw new IndexOutOfBoundsException(); + } + } + + private boolean isPositionIndex(int index) { + return index >= 0 && index <= size; + } + + private static class Node { + Object data; + Node next; + + public Node(Object data, Node next) { + this.data = data; + this.next = next; + } + } + + private Node node(int index) { + Node node = head; + for (int i = 0; i < index; i++) { + node = node.next; + } + return node; + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + Iterator iterator = iterator(); + LinkedList list = new LinkedList(); + while (iterator.hasNext()) { + list.addFirst(iterator.next()); + } + this.head = list.head; + this.tail = list.tail; + this.size = list.size; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + int count = size / 2; + if (count == 0) { + return; + } + Node newNode = node(count); + head = newNode; + size = size - count; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + checkPositionIndex(i); + checkPositionIndex(i + length); + for (int j = i; j < i + length; j++) { + remove(j); + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + int[] result = new int[list.size]; + int i = 0; + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + int position = (int) iterator.next(); + if (position >= 0 && position < size) { + int number = (int) get(position); + result[i++] = number; + } + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + LinkedList result = new LinkedList(); + Iterator iterator = iterator(); + Iterator iteratorB = list.iterator(); + while (iterator.hasNext() && iteratorB.hasNext()) { + int number1 = (int) iterator.next(); + int number2 = (int) iteratorB.next(); + while (number1 < number2) { + if (!iterator.hasNext()) { + break; + } + result.add(number1); + number1 = (int) iterator.next(); + } + while (number1 > number2) { + if (!iteratorB.hasNext()) { + break; + } + number2 = (int) iteratorB.next(); + } + } + while (iterator.hasNext()){ + result.add(iterator.next()); + } + head = result.head; + tail = result.tail; + size = result.size; + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + int prev; + int after; + LinkedList result = new LinkedList(); + Iterator iterator = iterator(); + if (iterator.hasNext()) { + prev = (int) iterator.next(); + result.add(prev); + } else { + return; + } + if (iterator.hasNext()) { + after = (int) iterator.next(); + } else { + return; + } + if (prev != after){ + result.add(after); + } + + + while (iterator.hasNext()) { + prev = after; + after = (int) iterator.next(); + if (prev != after) { + result.add(after); + } + } + + head = result.head; + tail = result.tail; + size = result.size; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + Iterator iterator = iterator(); + LinkedList result = new LinkedList(); + while (iterator.hasNext()) { + int number = (int) iterator.next(); + if (number <= min || number >= max) { + result.add(number); + } + } + head = result.head; + tail = result.tail; + size = result.size; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + LinkedList result = new LinkedList(); + Iterator iterator = iterator(); + Iterator iteratorB = list.iterator(); + while (iterator.hasNext() && iteratorB.hasNext()) { + int number1 = (int) iterator.next(); + int number2 = (int) iteratorB.next(); + while (number1 < number2) { + if (!iterator.hasNext()) { + break; + } + number1 = (int) iterator.next(); + } + while (number1 > number2) { + if (!iteratorB.hasNext()) { + break; + } + number2 = (int) iteratorB.next(); + } + if (number1 == number2) { + result.add(number1); + } + } + return result; + } + + public static void main(String[] args) { + LinkedList list = new LinkedList(); +// list.addLast(3); +// list.addLast(7); +// list.addLast(10); +// list.reverse(); +// System.out.println(); +// list.addLast(2); +// list.addLast(5); +// list.addLast(7); +// list.addLast(8); +// list.addLast(10); +// list.removeFirstHalf(); +// System.out.println(); + } +} diff --git a/group16/2816977791/thirdExercise/src/basic/LinkedListTest.java b/group16/2816977791/thirdExercise/src/basic/LinkedListTest.java new file mode 100644 index 0000000000..2d4667f822 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/basic/LinkedListTest.java @@ -0,0 +1,147 @@ +package basic; + +import org.junit.Test; + +/** + * @author nvarchar + * date 2017/3/28 + */ +public class LinkedListTest { + + @Test + public void reverse() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(3); + list.addLast(7); + list.addLast(10); + list.reverse(); + System.out.println(); + } + + @Test + public void removeFirstHalf() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(2); + list.addLast(5); + list.addLast(7); + list.addLast(8); + list.addLast(10); + list.removeFirstHalf(); + System.out.println(); + } + + @Test + public void remove() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(2); + list.addLast(5); + list.addLast(7); + list.addLast(8); + list.addLast(10); + list.remove(1, 2); + System.out.println(); + } + + @Test + public void getElements() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(11); + list.addLast(101); + list.addLast(201); + list.addLast(301); + list.addLast(401); + list.addLast(501); + list.addLast(601); + list.addLast(701); + + LinkedList listB = new LinkedList(); + listB.addLast(1); + listB.addLast(3); + listB.addLast(4); + listB.addLast(6); + list.getElements(listB); + + System.out.println(); + } + + @Test + public void subtract() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(11); + list.addLast(101); + list.addLast(201); + list.addLast(301); + list.addLast(401); + list.addLast(501); + list.addLast(601); + list.addLast(701); + + LinkedList listB = new LinkedList(); + listB.addLast(11); + listB.addLast(301); + listB.addLast(401); + listB.addLast(601); + list.subtract(listB); + + System.out.println(); + } + + @Test + public void removeDuplicateValues() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(11); + list.addLast(101); + list.addLast(101); + list.addLast(101); + list.addLast(101); + list.addLast(201); + list.addLast(301); + list.addLast(301); + list.addLast(401); + list.addLast(401); + list.addLast(501); + list.addLast(601); + list.addLast(601); + list.addLast(701); + list.removeDuplicateValues(); + System.out.println(); + } + + @Test + public void removeRange() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(11); + list.addLast(101); + list.addLast(201); + list.addLast(301); + list.addLast(401); + list.addLast(501); + list.addLast(601); + list.addLast(701); + list.removeRange(200, 500); + System.out.println(); + } + + @Test + public void intersection() throws Exception { + LinkedList list = new LinkedList(); + list.addLast(11); + list.addLast(101); + list.addLast(201); + list.addLast(301); + list.addLast(401); + list.addLast(501); + list.addLast(601); + list.addLast(701); + + LinkedList listB = new LinkedList(); + listB.addLast(11); + listB.addLast(301); + listB.addLast(401); + listB.addLast(601); + listB.addLast(901); + list.intersection(listB); + System.out.println(); + } + +} \ No newline at end of file diff --git a/group16/2816977791/thirdExercise/src/basic/List.java b/group16/2816977791/thirdExercise/src/basic/List.java new file mode 100644 index 0000000000..828053574c --- /dev/null +++ b/group16/2816977791/thirdExercise/src/basic/List.java @@ -0,0 +1,17 @@ +package basic; + +/** + * @author nvarchar + * date 2017/3/27 + */ +public interface List { + void add(Object o); + + void add(int index, Object o); + + Object get(int index); + + Object remove(int index); + + int size(); +} diff --git a/group16/2816977791/thirdExercise/src/impl/ConnectionImpl.java b/group16/2816977791/thirdExercise/src/impl/ConnectionImpl.java new file mode 100644 index 0000000000..01cd331d6a --- /dev/null +++ b/group16/2816977791/thirdExercise/src/impl/ConnectionImpl.java @@ -0,0 +1,64 @@ +package impl; + +import api.Connection; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class ConnectionImpl implements Connection { + + URL url; + + public ConnectionImpl(String urlString) { + try { + url = new URL(urlString); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + ByteArrayOutputStream baos = null; + try { + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream in = conn.getInputStream(); + baos = new ByteArrayOutputStream(); + int len = 0; + byte[] buffer = new byte[1024]; + while ((len = in.read(buffer)) != -1) { + baos.write(buffer, 0, len); + } + in.close(); + baos.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + HttpURLConnection conn = null; + try { + conn = (HttpURLConnection) url.openConnection(); + return conn.getContentLength(); + } catch (IOException e) { + return -1; + } finally { + conn.disconnect(); + } + } + + @Override + public void close() { + + } + +} diff --git a/group16/2816977791/thirdExercise/src/impl/ConnectionManagerImpl.java b/group16/2816977791/thirdExercise/src/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..157f4fd9b0 --- /dev/null +++ b/group16/2816977791/thirdExercise/src/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package impl; + +import api.Connection; +import api.ConnectionException; +import api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + Connection connection = new ConnectionImpl(url); + return connection; + } + +} diff --git a/group16/313001956/.classpath b/group16/313001956/.classpath index b42037dde2..249d4729ec 100644 --- a/group16/313001956/.classpath +++ b/group16/313001956/.classpath @@ -8,5 +8,6 @@ + diff --git a/group16/313001956/RemoteSystemsTempFiles/.project b/group16/313001956/RemoteSystemsTempFiles/.project new file mode 100644 index 0000000000..5447a64fa9 --- /dev/null +++ b/group16/313001956/RemoteSystemsTempFiles/.project @@ -0,0 +1,12 @@ + + + RemoteSystemsTempFiles + + + + + + + org.eclipse.rse.ui.remoteSystemsTempNature + + diff --git a/group06/1378560653/src/com/coderising/litestruts/structs.xml b/group16/313001956/WebContent/WEB-INF/resource/struts.xml similarity index 100% rename from group06/1378560653/src/com/coderising/litestruts/structs.xml rename to group16/313001956/WebContent/WEB-INF/resource/struts.xml diff --git a/group16/313001956/src/com/coderising/array/ArrayUtil.java b/group16/313001956/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..158b1bc6df --- /dev/null +++ b/group16/313001956/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,202 @@ + +package com.coderising.array; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; + +import com.coding.basic.ArrayList; + +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 size = origin.length; + if (size == 0) { + return; + } + int semi = size / 2; + int temp; + for (int i = 0; i < semi; i++) { + temp = origin[i]; + origin[i] = origin[size - 1 - i]; + origin[size - 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 int[] removeZero(int[] oldArray) { + ArrayList arrayList = new ArrayList(); + int size = oldArray.length; + for (int i = 0; i < size; i++) { + if (oldArray[i] != 0) + arrayList.add(oldArray[i]); + } + + return arrayListToArray(arrayList); + } + + /** + * Ѿõ飬 a1a2 , һµa3, ʹa3 a1a2 Ԫأ Ȼ 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 arraylist = new ArrayList(); + int size1 = array1.length; + int size2 = array2.length; + int j = 0; + for (int i = 0; i < size1; i++) { + if (j >= size2) + arraylist.add(array1[i]); + else { + for (; j < size2; j++) { + if (array1[i] < array2[j]) { + arraylist.add(array1[i]); + break; + } else if (array1[i] == array2[j]) { + arraylist.add(array2[j]); + j++; + break; + } else { + arraylist.add(array2[j]); + } + } + } + } + return arrayListToArray(arraylist); + } + + private int[] arrayListToArray(ArrayList arraylist) { + int newSize = arraylist.size(); + int[] newArray = new int[newSize]; + for (int i = 0; i < newSize; i++) + newArray[i] = Integer.parseInt(arraylist.get(i).toString()); + return newArray; + } + + /** + * һѾݵ 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) { + int newsize = oldArray.length + size; + int[] newArray = new int[newsize]; + System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); + return newArray; + } + + /** + * 쳲Ϊ1123581321...... һֵ Сڸֵ 磬 max = 15 , + * 򷵻صӦΪ [11235813] max = 1, 򷵻ؿ [] + * + * @param max + * @return + */ + public int[] fibonacci(int max) { + int array[] = null; + ArrayList arraylist = new ArrayList(); + arraylist.add(1); + arraylist.add(1); + if (max == 1) + return null; + int temp = 1; + for (int i = 1; (temp = Integer.parseInt(arraylist.get(i).toString()) + + Integer.parseInt(arraylist.get(i - 1).toString())) <= max; i++) { + + arraylist.add(temp); + } + + return arrayListToArray(arraylist); + } + + /** + * Сڸֵmax max = 23, صΪ[2,3,5,7,11,13,17,19] + * + * @param max + * @return + */ + public int[] getPrimes(int max) { + ArrayList al = new ArrayList(); + if (max == 1) { + return null; + } else if (max == 2) { + al.add(2); + } else { + for (int i = 2; i < max; i++) { + for (int j = 2; j <= Math.sqrt(max); j++) { + if (i % j == 0) + break; + } + al.add(i); + } + } + return arrayListToArray(al); + } + + /** + * ν ָǡõ֮ͣ6=1+2+3 һֵmax һ飬 Сmax + * + * @param max + * @return + */ + public int[] getPerfectNumbers(int max) { + ArrayList al = new ArrayList(); + int num = 0; + for (int i = 1; i < max; i++) { + num = 0; + for (int j = 1; j < i; j++) { + if (i % j == 0) + num += j; + } + if (num == i) + al.add(i); + } + return arrayListToArray(al); + } + + /** + * seperator array array= [3,8,9], seperator = "-" 򷵻ֵΪ"3-8-9" + * + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator) { + String s = ""; + int lenth = array.length; + for (int i = 0; i < lenth; i++) { + if (i == 0) + s += i; + else { + s += seperator + i; + } + } + return s; + } + +} diff --git a/group16/313001956/src/com/coderising/download/DownloadThread.java b/group16/313001956/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..0653f71d80 --- /dev/null +++ b/group16/313001956/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,57 @@ +package com.coderising.download; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.DownloadListener; +import com.coding.basic.ArrayList; + +public class DownloadThread extends Thread { + + Connection conn; + Integer startPos; + Integer endPos; + DownloadListener listener; + File file; + int threadNum; + ArrayList threadDone; + + public DownloadThread(Connection conn, int startPos, int endPos, DownloadListener listener, File file, + Integer threadNum, ArrayList threadDone) { + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.listener = listener; + this.file = file; + this.threadNum = threadNum; + this.threadDone = threadDone; + // run(); + } + + @Override + public synchronized void run() { + try { + byte[] bt = conn.read(startPos, endPos, file); + + threadDone.add(1); + + if (conn != null) { + conn.close(); + } + if (threadDone.size() == threadNum) { + + listener.notifyFinished(); + } + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/group16/313001956/src/com/coderising/download/FileDownloader.java b/group16/313001956/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..6903506b6b --- /dev/null +++ b/group16/313001956/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,97 @@ +package com.coderising.download; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.util.List; + +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.coding.basic.ArrayList; + +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, Ƕ߳أ Ŀͻ˲֪ʲôʱҪʵֵ + // ̶ִ߳Ժ listenernotifiedFinished ͻ˾յ֪ͨ + // ʵ˼· + // 1. ҪConnectionManageropenӣ + // ȻͨConnection.getContentLengthļij + // 2. 3߳أ עÿ߳ҪȵConnectionManageropen + // Ȼread readжȡļĿʼλúͽλõIJ ֵbyte[] + // 3. byteд뵽ļ + // 4. е̶߳Ժ ҪlistenernotifiedFinished + + // Ĵʾ룬 Ҳ˵ֻһ̣߳ Ҫɶ̵߳ġ + Connection conn = null; + try { + Integer threadNum = 3; + //Integer threadDone = 0; + ArrayList threadDone=new ArrayList(); + conn = cm.open(this.url); + if (conn.getConn().getResponseCode() == 200) { + int length = conn.getContentLength(); + int size = (length % threadNum == 0 ? length / threadNum : length / threadNum + 1); + + String filename = url.substring(url.lastIndexOf('/')); + String filePath = "C:\\Users\\Administrator\\Desktop\\" + filename; + File file = new File(filePath); + RandomAccessFile raf = new RandomAccessFile(file, "rw"); + raf.setLength(length); + raf.close(); + + for (int i = 0; i < threadNum; i++) { + Connection connThread = cm.open(this.url); + new DownloadThread(connThread, i * size, (i + 1) * size - 1, listener, file, threadNum, + threadDone).start(); + } + } + } catch (ConnectionException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + 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/group16/313001956/src/com/coderising/download/FileDownloaderTest.java b/group16/313001956/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..cca82ea5da --- /dev/null +++ b/group16/313001956/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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://10.10.1.65:1024/wxl.jpg"; + String url = "http://10.10.1.65:1024/java.pdf"; + 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/group16/313001956/src/com/coderising/download/api/Connection.java b/group16/313001956/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..3a3edf5835 --- /dev/null +++ b/group16/313001956/src/com/coderising/download/api/Connection.java @@ -0,0 +1,43 @@ +package com.coderising.download.api; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.HttpURLConnection ; + +public interface Connection { + URL fileurl = null; + HttpURLConnection conn = null; + InputStream inStream = null; + + /** + * ʼͽλã ȡݣ ֵֽ + * + * @param startPos + * ʼλã 0ʼ + * @param endPos + * λ + * @return + */ + public byte[] read(int startPos, int endPos,File file) throws IOException; + + /** + * õݵij + * + * @return + */ + public int getContentLength(); + + /** + * ر + */ + public void close(); + + public void setConn(HttpURLConnection conn); + public void setFileurl(URL fileurl); + public HttpURLConnection getConn(); + public URL getFileurl(URL fileurl) ; + public void setinStream(InputStream inStream); + public InputStream getinStream(); +} diff --git a/group16/313001956/src/com/coderising/download/api/ConnectionException.java b/group16/313001956/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group16/313001956/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group16/313001956/src/com/coderising/download/api/ConnectionManager.java b/group16/313001956/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group16/313001956/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/group16/313001956/src/com/coderising/download/api/DownloadListener.java b/group16/313001956/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group16/313001956/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/group16/313001956/src/com/coderising/download/impl/ConnectionImpl.java b/group16/313001956/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..94fd2c9b67 --- /dev/null +++ b/group16/313001956/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,80 @@ +package com.coderising.download.impl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.URL; +import java.net.HttpURLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection { + URL fileurl = null; + HttpURLConnection uRLconn = null; + InputStream inStream = null; + + @Override + public byte[] read(int startPos, int endPos, File file) throws IOException { + uRLconn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + if (inStream == null) + inStream = uRLconn.getInputStream(); + int size = endPos - startPos + 1; + + byte[] bt = new byte[size]; + + RandomAccessFile raf = new RandomAccessFile(file, "rw"); + + raf.seek(startPos); + int lenth=0; + //lenth = inStream.read(bt,0,size); + while ((lenth = inStream.read(bt,0,size)) != -1) + raf.write(bt, 0, lenth); + raf.close(); + + return bt; + + } + + @Override + public int getContentLength() { + int fileSize = uRLconn.getContentLength(); + return fileSize; + } + + @Override + public void close() { + if (inStream != null) + try { + inStream.close(); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void setConn(HttpURLConnection uRLconn) { + this.uRLconn = uRLconn; + } + + public HttpURLConnection getConn() { + return this.uRLconn; + } + + public void setFileurl(URL fileurl) { + this.fileurl = fileurl; + } + + public URL getFileurl(URL fileurl) { + return this.fileurl; + } + + public void setinStream(InputStream inStream) { + this.inStream = inStream; + } + + public InputStream getinStream() { + return this.inStream; + } +} diff --git a/group16/313001956/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group16/313001956/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..ff96aaa595 --- /dev/null +++ b/group16/313001956/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,35 @@ +package com.coderising.download.impl; + +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 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 fileurl=new URL(url); + HttpURLConnection uRlconn = (HttpURLConnection)fileurl.openConnection(); + //ӵ + uRlconn.setRequestMethod("GET"); + uRlconn.setReadTimeout(5000); + Connection conn = new ConnectionImpl(); + conn.setFileurl(fileurl); + + conn.setConn(uRlconn); + return conn; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/group16/313001956/src/com/coderising/jvm/loader/ClassFileLoader.java b/group16/313001956/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..2b7607a09e --- /dev/null +++ b/group16/313001956/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + static final int BUFF_SIZE=1024; + + public byte[] readBinaryCode(String className) { + byte[] barray = new byte[BUFF_SIZE]; + try { + + String pathname = clzPaths.get(0) + "\\" + className.replace('.', '\\')+".class"; + File file = new File(pathname); + InputStream in = new FileInputStream(file); + int byteread = 0; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while ((byteread = in.read(barray)) != -1) { + baos.write(barray, 0, byteread); + } + return baos.toByteArray(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + int clzsize = clzPaths.size(); + String str = ""; + if (clzsize > 0) { + for (int i = 0; i < clzsize; i++) { + str += clzPaths.get(i); + if (i < clzsize - 1) { + str += ";"; + } + } + } + return str; + } + +} diff --git a/group16/313001956/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group16/313001956/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..6edfd64a18 --- /dev/null +++ b/group16/313001956/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 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + static String path1 = "D:\\Java2017\\GitHub\\coding2017\\group16\\313001956\\build\\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 parameters) { + + /* + * + * 0. ȡļstruts.xml + * + * 1. actionNameҵӦclass LoginAction, ͨʵ + * parametersеݣösetter parametersе ("name"="test" , + * "password"="1234") , ǾӦõ setNamesetPassword + * + * 2. ͨöexectue ÷ֵ"success" + * + * 3. ͨҵgetter getMessage, ͨã ֵγһHashMap , + * {"message": "¼ɹ"} , ŵViewparameters + * + * 4. struts.xmlе ,Լexecuteķֵ ȷһjsp + * ŵViewjspֶС + * + */ + View view = new View(); + Map map = new HashMap(); + view.setParameters(map); + try { + + SAXReader reader = new SAXReader(); + String dir = System.getProperty("user.dir"); + + Document document = reader.read(new File(dir + "/src/com/coderising/litestruts/struts.xml")); + Element struts = document.getRootElement(); + java.util.List list_action = struts.elements("action"); + + Element item = null; + for (int i = 0; i < list_action.size(); i++) { + item = list_action.get(i); + String nm = item.attributeValue("name"); + if (actionName.equals(nm)) { + break; + } + } + String str_class = item.attributeValue("class"); + // String real_class=dir+"/"+str_class.replace('.', '/'); + // Class cl = Class.forName( dir.replace('\\', + // '.')+".src."+str_class); + Class cl = Class.forName(str_class); + Object instance = cl.newInstance(); + + String dNmae = parameters.get("name"); + String dpassword = parameters.get("password"); + Method mName = cl.getMethod("setName", String.class); + Method mPassword = cl.getMethod("setPassword", String.class); + mName.invoke(instance, dNmae); + mPassword.invoke(instance, dpassword); + + Method mExectue = cl.getMethod("execute"); + Object result = mExectue.invoke(instance); + + Method[] methods = cl.getMethods(); + for (Method method : methods) { + if (isGetter(method)) { + String mGettername = method.getName().substring(3); + Object mResult = method.invoke(instance); + view.getParameters().put(mGettername.toLowerCase(), mResult); + } + } + + java.util.List resulList = item.elements(); + for (Element el : resulList) { + if (result.toString().equals(el.attributeValue("name"))) { + view.setJsp(el.getTextTrim()); + break; + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + return view; + } + + // жǷgetter + public static boolean isGetter(Method method) { + if (!method.getName().startsWith("get")) + return false; + if (method.getParameterTypes().length != 0) + return false; + if (void.class.equals(method.getReturnType())) + return false; + return true; + } + +} diff --git a/group16/313001956/src/com/coderising/litestruts/StrutsTest.java b/group16/313001956/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..9e98836f5f --- /dev/null +++ b/group16/313001956/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"); //ԤIJһ + + 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/group16/313001956/src/com/coderising/litestruts/View.java b/group16/313001956/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..f1e7fcfa19 --- /dev/null +++ b/group16/313001956/src/com/coderising/litestruts/View.java @@ -0,0 +1,26 @@ +package com.coderising.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/group16/313001956/src/com/coderising/litestruts/struts.xml b/group16/313001956/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..ff7623e6e1 --- /dev/null +++ b/group16/313001956/src/com/coderising/litestruts/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/group16/313001956/src/com/coding/basic/ArrayList.java b/group16/313001956/src/com/coding/basic/ArrayList.java index 3bec144013..03d2547c30 100644 Binary files a/group16/313001956/src/com/coding/basic/ArrayList.java and b/group16/313001956/src/com/coding/basic/ArrayList.java differ diff --git a/group16/313001956/src/com/coding/basic/LinkedList.java b/group16/313001956/src/com/coding/basic/LinkedList.java index de886c9084..483ca7ac44 100644 Binary files a/group16/313001956/src/com/coding/basic/LinkedList.java and b/group16/313001956/src/com/coding/basic/LinkedList.java differ diff --git a/group16/313001956/src/com/coding/basic/LinkedListTest.java b/group16/313001956/src/com/coding/basic/LinkedListTest.java new file mode 100644 index 0000000000..2acd774160 --- /dev/null +++ b/group16/313001956/src/com/coding/basic/LinkedListTest.java @@ -0,0 +1,28 @@ +package com.coding.basic; + +import org.junit.Assert; +import org.junit.Test; + +public class LinkedListTest { + + @Test + public final void testReverse() { + + LinkedList list=new LinkedList(); + list.add(3); + list.add(7); + list.add(10); + + LinkedList testlist=new LinkedList(); + testlist.add(10); + testlist.add(7); + testlist.add(3); + + list.reverse(list); + Assert.assertEquals(list.size(), testlist.size()); + Assert.assertEquals(list.get(0), testlist.get(0)); + Assert.assertEquals(list.get(1), testlist.get(1)); + Assert.assertEquals(list.get(2), testlist.get(2)); + } + +} diff --git a/group16/313001956/src/com/coding/basic/linklist/LRUPageFrame.java b/group16/313001956/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..e689ae03ce --- /dev/null +++ b/group16/313001956/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,135 @@ +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; + first = null; + last = null; + } + + /** + * ȡж + * + * @param key + * @return + */ + public void access(int pageNum) { + Node node = new Node(); + node.prev = null; + node.pageNum = pageNum; + + if (first == null) { + node.next = null; + first = node; + return; + } + if(judgeEqual(node, pageNum)){ + return; + } + + node.next = first; + first.prev = node; + first = node; + + if (last == null) { + judgeFull(); + } else { + Node temp = last.prev; + + last.prev = null; + last.next = null; + last.pageNum = 0; + + temp.next = null; + last = temp; + } + } + + private boolean judgeEqual(Node node, int pageNum) { + if (first.pageNum == pageNum) { + return true; + } + Node nd = first; + while (nd != null) { + if (nd.pageNum == pageNum) { + if (nd.next != null) { + nd.prev.next = nd.next; + nd.next.prev = nd.prev; + nd.prev = null; + nd.next = first; + first = nd; + } else { + if (last != null) { + last = nd.prev; + } + nd.prev.next = null; + + nd.prev = null; + nd.next = first; + first.prev=nd; + first = nd; + } + + return true; + } + nd = nd.next; + } + return false; + } + + // жǷ˲last + private void judgeFull() { + int count = 0; + Node node = first; + while (node != null) { + count++; + if (count == this.capacity) { + last = node; + return; + } + node = node.next; + } + + if (count >= this.capacity) { + + } + } + + 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/group16/313001956/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group16/313001956/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..d1e58e2405 --- /dev/null +++ b/group16/313001956/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,35 @@ +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()); + frame.access(0); + Assert.assertEquals("0,4,3", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,4", frame.toString()); + } + +} diff --git a/group16/420355244/Homework2/src/com/coderising/array/ArrayUtil.java b/group16/420355244/Homework2/src/com/coderising/array/ArrayUtil.java index 5fd5f1efba..2c1fca67d4 100644 --- a/group16/420355244/Homework2/src/com/coderising/array/ArrayUtil.java +++ b/group16/420355244/Homework2/src/com/coderising/array/ArrayUtil.java @@ -26,16 +26,21 @@ public static void reverseArray(int[] origin){ */ public static int[] removeZero(int[] oldArray){ - for(int i = 0;i < oldArray.length ;i++){ + int zeroCount = 0; + for(int i = 0;i < oldArray.length; i++){ if(oldArray[i] == 0){ - int[] a = {}; - System.arraycopy(oldArray, 0, a, 0, i); - System.arraycopy(oldArray, 0, a, i, oldArray.length); - oldArray = a; - removeZero(oldArray); + zeroCount++; } } - return oldArray; + int[] newArr = new int[oldArray.length - zeroCount]; + int index = 0; + for(int i = 0;i < oldArray.length; i++){ + if(oldArray[i] != 0){ + newArr[index] = oldArray[i]; + index++; + } + } + return newArr; } /** @@ -47,7 +52,45 @@ public static int[] removeZero(int[] oldArray){ */ public static int[] merge(int[] array1, int[] array2){ - return null; + //先对数组进行去重,记录重复的索引,后将两个数组合并,再进行排序 + int[] repeatedNum = new int[array1.length + array2.length]; + int repeatedCount = 0; + for(int i = 0;i < array1.length; i++){ + for(int j = 0;j < array2.length; j++){ + if(array1[i] == array2[j]){ + repeatedNum[repeatedCount] = array1[i]; + repeatedCount++; + } + } + } + int [] combineArr = new int[array1.length + array2.length - repeatedCount]; + for(int i = 0;i < array1.length; i++){ + combineArr[i] = array1[i]; + } + for(int i = 0;i < array2.length; i++){ + int index = array1.length -1; + boolean same = false; + for(int j = 0;j < repeatedNum.length; j++){ + if(array2[i] == repeatedNum[j]){ + same = true; + } + } + if(!same){ + index += 1; + combineArr[index] = array2[i]; + } + } + //冒泡排序 + for(int i = 0;i < combineArr.length;i++){ + for(int j = i + 1;j < combineArr.length;j++){ + if(combineArr[i] > combineArr[j]){ + int x = combineArr[i]; + combineArr[i] = combineArr[j]; + combineArr[j] = x; + } + } + } + return combineArr; } /** * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size @@ -59,7 +102,11 @@ public static int[] merge(int[] array1, int[] array2){ * @return */ public static int[] grow(int [] oldArray, int size){ - return null; + int[] newArr = new int[oldArray.length + size]; + for(int i = 0;i < oldArray.length; i++){ + newArr[i] = oldArray[i]; + } + return newArr; } /** @@ -70,7 +117,31 @@ public static int[] grow(int [] oldArray, int size){ * @return */ public static int[] fibonacci(int max){ - return null; + if(max == 1){ + return null; + }else{ + int length = 0; + int dataBefore = 0; + int dataAfter = 1; + while(dataAfter < max){ + int date = dataAfter; + dataAfter = dataAfter + dataBefore; + dataBefore = date; + length++; + } + int index = 0; + int[] result = new int[length]; + dataBefore = 0; + dataAfter = 1; + while(dataAfter < max){ + result[index] = dataAfter; + int date = dataAfter; + dataAfter = dataAfter + dataBefore; + dataBefore = date; + index ++; + } + return result; + } } /** @@ -80,6 +151,12 @@ public static int[] fibonacci(int max){ * @return */ public static int[] getPrimes(int max){ + int i = 1; + int length = 0; + while(i < max){ + i++; + int search = 1; + } return null; } @@ -102,7 +179,14 @@ public static int[] getPerfectNumbers(int max){ * @return */ public static String join(int[] array, String seperator){ - return null; + StringBuilder sb = new StringBuilder(); + for(int i=0 ;i < array.length; i++){ + sb.append(String.valueOf(array[i])); + if(i != array.length - 1){ + sb.append(seperator); + } + } + return sb.toString(); } public static void main(String[] args) { @@ -111,9 +195,29 @@ public static void main(String[] args) { for (int i : a) { System.out.print(i+","); }*/ - int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} ; - removeZero(oldArr); - for (int i : oldArr) { + /*int[] oldArr = {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} ; + int[] newArr = removeZero(oldArr); + for (int i : newArr) { + System.out.print(i+","); + }*/ + /*int[] a1 = {3, 5, 7,8}; + int[] a2 = {4, 5, 6,7}; + int[] merge = merge(a1,a2); + for (int i : merge) { + System.out.print(i+","); + }*/ + /*int[] oldArray = {2,3,6}; + int size = 3; + int[] newArr = grow(oldArray, size); + for (int i : newArr) { + System.out.print(i+","); + }*/ + /*int[] array= {3,8,9}; + String seperator = "-"; + String join = join(array, seperator); + System.out.println(join);*/ + int[] fibonacci = fibonacci(15); + for (int i : fibonacci) { System.out.print(i+","); } } diff --git a/group16/420355244/Homework3/.classpath b/group16/420355244/Homework3/.classpath new file mode 100644 index 0000000000..3e0fb272a8 --- /dev/null +++ b/group16/420355244/Homework3/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/group14/187114392/work_1_20170225/.gitignore b/group16/420355244/Homework3/.gitignore similarity index 100% rename from group14/187114392/work_1_20170225/.gitignore rename to group16/420355244/Homework3/.gitignore diff --git a/group16/1012075117/DataStructure219/.project b/group16/420355244/Homework3/.project similarity index 91% rename from group16/1012075117/DataStructure219/.project rename to group16/420355244/Homework3/.project index 567baae65f..57ff5cb4f2 100644 --- a/group16/1012075117/DataStructure219/.project +++ b/group16/420355244/Homework3/.project @@ -1,6 +1,6 @@ - DataStructure219 + Homework3 diff --git a/group16/420355244/Homework3/src/com/coderising/array/ArrayUtil.java b/group16/420355244/Homework3/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..e5ddb476a6 --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coderising/download/DownloadThread.java b/group16/420355244/Homework3/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..900a3ad358 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,20 @@ +package com.coderising.download; + +import com.coderising.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/group16/420355244/Homework3/src/com/coderising/download/FileDownloader.java b/group16/420355244/Homework3/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c3c8a3f27d --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,73 @@ +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; + + +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/group16/420355244/Homework3/src/com/coderising/download/FileDownloaderTest.java b/group16/420355244/Homework3/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..4ff7f46ae0 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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://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/group16/420355244/Homework3/src/com/coderising/download/api/Connection.java b/group16/420355244/Homework3/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coderising/download/api/ConnectionException.java b/group16/420355244/Homework3/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group16/420355244/Homework3/src/com/coderising/download/api/ConnectionManager.java b/group16/420355244/Homework3/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coderising/download/api/DownloadListener.java b/group16/420355244/Homework3/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionImpl.java b/group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..36a9d2ce15 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,27 @@ +package com.coderising.download.impl; + +import java.io.IOException; + +import com.coderising.download.api.Connection; + +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/group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..172371dd55 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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 null; + } + +} diff --git a/group16/420355244/Homework3/src/com/coderising/litestruts/LoginAction.java b/group16/420355244/Homework3/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coderising/litestruts/Struts.java b/group16/420355244/Homework3/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..85e2e22de3 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,34 @@ +package com.coderising.litestruts; + +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/group16/420355244/Homework3/src/com/coderising/litestruts/StrutsTest.java b/group16/420355244/Homework3/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coderising/litestruts/View.java b/group16/420355244/Homework3/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group16/420355244/Homework3/src/com/coderising/litestruts/struts.xml b/group16/420355244/Homework3/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..171848ecd1 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coderising/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/group16/420355244/Homework3/src/com/coding/basic/ArrayList.java b/group16/420355244/Homework3/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..1f185736f9 --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coding/basic/BinaryTreeNode.java b/group16/420355244/Homework3/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group16/420355244/Homework3/src/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/group16/420355244/Homework3/src/com/coding/basic/Iterator.java b/group16/420355244/Homework3/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..06ef6311b2 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coding/basic/Iterator.java @@ -0,0 +1,7 @@ +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/LinkedList.java b/group16/420355244/Homework3/src/com/coding/basic/LinkedList.java similarity index 98% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/LinkedList.java rename to group16/420355244/Homework3/src/com/coding/basic/LinkedList.java index fdae519c0a..4fdb03db8a 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/LinkedList.java +++ b/group16/420355244/Homework3/src/com/coding/basic/LinkedList.java @@ -1,4 +1,6 @@ -package com.github.eulerlcs.jmr.multiDL.algorithm; +package com.coding.basic; + + public class LinkedList implements List { diff --git a/group16/420355244/Homework3/src/com/coding/basic/List.java b/group16/420355244/Homework3/src/com/coding/basic/List.java new file mode 100644 index 0000000000..10d13b5832 --- /dev/null +++ b/group16/420355244/Homework3/src/com/coding/basic/List.java @@ -0,0 +1,9 @@ +package com.coding.basic; + +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/group16/420355244/Homework3/src/com/coding/basic/Queue.java b/group16/420355244/Homework3/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..36e516e266 --- /dev/null +++ b/group16/420355244/Homework3/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/group16/420355244/Homework3/src/com/coding/basic/Stack.java b/group16/420355244/Homework3/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..a5a04de76d --- /dev/null +++ b/group16/420355244/Homework3/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/group16/502059278/src/cn/mark/work0219/MyLinkedList.java b/group16/502059278/src/cn/mark/work0219/MyLinkedList.java index 896d7bcb79..22d0027941 100644 --- a/group16/502059278/src/cn/mark/work0219/MyLinkedList.java +++ b/group16/502059278/src/cn/mark/work0219/MyLinkedList.java @@ -7,23 +7,25 @@ public class MyLinkedList implements MyList{ private Node head; + private Node last; private int size;//集合的长度 + + public MyLinkedList(){ + this.head = new Node(null); + } /** * 添加元素 */ @Override public boolean add(Object o) { - //为空判断 - if ( o == null ){ - System.out.println("不允许null的元素插入!"); - return false; - } - if(head == null){ - head = new Node(); - head.data = o; - }else{ - + if (this.last == null){ + this.last = new Node(o); + this.last.pre = this.head; + this.last.next = this.last; + } else { + Node oldLast = this.last; + this.last = new Node(o); } return false; @@ -49,13 +51,18 @@ public Object remove(int index) { @Override public int size() { - // TODO Auto-generated method stub - return 0; + return this.size; } private static class Node{ Object data; + Node pre; Node next; + + + Node(Object data){ + this.data = data; + } } diff --git a/group16/502059278/src/cn/mark/work0312/MutiDownload.java b/group16/502059278/src/cn/mark/work0312/MutiDownload.java new file mode 100644 index 0000000000..116d81267b --- /dev/null +++ b/group16/502059278/src/cn/mark/work0312/MutiDownload.java @@ -0,0 +1,163 @@ +package cn.mark.work0312; + +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * 多线程下载 + */ +public class MutiDownload { + /*线程数*/ + private static final int THREAD_COUNT = 5; + /*下载资源*/ + private static final String DOWNLOAD_URL = "http://cn.bing.com/az/hprichbg/rb/PlungeDiving_ZH-CN11143756334_1920x1080.jpg"; + /*下载位置*/ + private static final String FILE_NAME = "D:/down.jpg"; + + public static void main(String[] args) { + //文件大小 + long fileSize; + HttpURLConnection connection = null; + try{ + //打开一个链接 + connection = (HttpURLConnection) new URL(DOWNLOAD_URL).openConnection(); + //设置请求方式 + connection.setRequestMethod("GET"); + //连接超时 + connection.setConnectTimeout(8000); + //读取超时 + connection.setReadTimeout(8000); + + if ( connection.getResponseCode() == 200 ){//请求成功返回200 + //文件大小 + fileSize = connection.getContentLength(); + //每个线程要读取的块 + long eachSize = fileSize / THREAD_COUNT; + + //打开一个RandomAccessFile文件,打开方式为读写(rw) + RandomAccessFile raf = new RandomAccessFile(FILE_NAME,"rw"); + //setLength是先在存储设备占用一块空间,防止下载到一半空间不足 + raf.setLength(fileSize); + raf.close(); + + /*创建线程开始下载*/ + for ( int i =0; i size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + } + + public void addFirst(Object o){ + add(0, o); + } + + public void addLast(Object o){ + add(size, o); + } + + public Object removeFirst(){ + return remove(0); + } + + public Object removeLast(){ + return remove(size-1); + } + + public Iterator iterator(){ + return new LinkedListIterator(this); + } + + private class LinkedListIterator implements Iterator{ + private LinkedList list; + private int position; + + public LinkedListIterator(LinkedList list) { + this.list=list; + } + + @Override + public boolean hasNext() { + if (position+1>size()){ + return false; + } + return true; + } + + @Override + public Object next() { + return list.get(position++); + } + + } + + @Override + public String toString(){ + for (int i = 0; i 7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Stack stack=new Stack<>(); + while (size()>0) { + stack.add(remove(0)); + } + + while (!stack.isEmpty()) { + this.add(stack.pop()); + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + for (int i = 0; i < size()/2; i++) { + removeFirst(); + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + + checkPositionIndex(i); + checkPositionIndex(i+length-1); + + for (int j = 0; j < length; j++) { + remove(i); + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] result=new int[list.size]; + + for (int i = 0; i < list.size; i++) { + result[i]=(int)get((Integer)list.get(i)); + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * @param list + */ + + public void subtract(LinkedList list){ + int k=0; + for (int i = size()-1; i >=0; i--) { + + for (int j = k; j < list.size(); j++) { + if (get(i).equals(list.get(j))) { + remove(i); + k=j; + break; + } + } + + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + for (int i = size()-2; i >=0; i--) { + if (get(i).equals(get(i+1))) { + remove(i); + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + int start=-1; + int end=-1; + for (int i = 0; i < size(); i++) { + if ((int)get(i)>min) { + start=i; + break; + } + } + for (int i = size()-1; i >=0; i--) { + if ((int)get(i)101->201->301->401->501->601->701 + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + LinkedList listB=new LinkedList(); + listB.add(1); + listB.add(3); + listB.add(4); + listB.add(6); + + System.out.println(Arrays.toString(list.getElements(listB))); + } + + //removeRange + @Test + public void subtract(){ + LinkedList list=new LinkedList(); + // 11->101->201->301->401->501->601->701 + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + LinkedList listB=new LinkedList(); + listB.add(201); + listB.add(601); + listB.add(401); + + list.subtract(listB); + list.toString(); + } + + @Test + public void removeDuplicateValues(){ + LinkedList list=new LinkedList(); + // 11->101->201->301->401->501->601->701 + list.add(11); + list.add(101); + list.add(301); + list.add(301); + list.add(401); + list.add(401); + list.add(601); + list.add(701); + + list.removeDuplicateValues(); + list.toString(); + } + + //intersection + @Test + public void removeRange(){ + LinkedList list=new LinkedList(); + // 11->101->201->301->401->501->601->701 + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + list.removeRange(800,900); + list.toString(); + } + + @Test + public void intersection(){ + LinkedList list=new LinkedList(); + // 11->101->201->301->401->501->601->701 + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + LinkedList listB=new LinkedList(); + listB.add(22); + listB.add(201); + listB.add(401); + listB.add(601); + listB.add(801); + + list.intersection(listB).toString(); + } +} diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java index 6a94ded0a9..3c3462637e 100644 --- a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java +++ b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java @@ -4,8 +4,6 @@ public class LinkedList implements List { private Node head; private int size = 0; - private Iterator iterator = new LinkedListIterator(); - public void add(Object o) { Node newNode = new Node(o, null); @@ -98,8 +96,8 @@ public Object removeLast() { return remove(size - 1); } - public Iterator iterator() { - return iterator; + public LinkedListIterator iterator() { + return new LinkedListIterator(head); } private void checkIndex(int index) { @@ -114,6 +112,22 @@ private void checkForAdd(int index) { } } + + @Override + public String toString() { + Iterator iterator = iterator(); + StringBuilder builder = new StringBuilder("["); + while ((iterator.hasNext())) { + builder.append(iterator.next()).append(','); + } + if (size() > 0) { + builder.deleteCharAt(builder.length() - 1); + } + return builder + .append(']') + .toString(); + } + /** * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 @@ -122,17 +136,18 @@ public void reverse() { if (size == 0) { return; } - Node[] nodes = new Node[size]; + Object[] datas = new Object[size]; int i = 0; // 迭代链表的数据生成数组 + Iterator iterator = iterator(); while (iterator.hasNext()) { - nodes[i++] = (Node) iterator.next(); + datas[i++] = iterator.next(); } // 遍历数组越生成新的 链表 - Node newHead = nodes[--i]; - Node next = newHead.next; + Node newHead = new Node(datas[--i], null); + Node next = newHead; for (int j = --i; j >= 0; j--) { - next.next = nodes[j]; + next.next = new Node(datas[j], null); next = next.next; } @@ -146,9 +161,23 @@ public void reverse() { * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf() { + removeFirstSize(size >> 1); + } + public void removeFirstSize(int firstSize) { + firstSize = firstSize > size() ? size() : firstSize; + LinkedListIterator iterator = iterator(); + int i = 1; + while (i++ <= firstSize) { + iterator.nextNode(); + } + if (size > 0) { + head = iterator.nextNode(); + size = size() - firstSize; + } } + /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * @@ -156,6 +185,21 @@ public void removeFirstHalf() { * @param length */ public void remove(int i, int length) { + if (i == 0 ) {removeFirstSize(length); return;} + if (i >= size || length == 0) {return;} + + int lastLenth = size - i; + length = length <= lastLenth? length : lastLenth; + Node pre = node(i-1); + int j = 0; + + Node next = pre; + while (j++ < length){ + next = next.next; + } + pre.next = next.next; + size = size - length; + } @@ -229,6 +273,13 @@ private class LinkedListIterator implements Iterator { private Node next; + public LinkedListIterator() { + } + + private LinkedListIterator(Node next) { + this.next = next; + } + @Override public boolean hasNext() { return next != null; @@ -243,5 +294,15 @@ public Object next() { next = next.next; return ret.data; } + + + private Node nextNode() { + if (next == null) { + throw new IndexOutOfBoundsException("there is no node in list"); + } + Node ret = next; + next = next.next; + return ret; + } } } diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/List.java b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/List.java index 396b1f6416..0a09990083 100644 --- a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/List.java +++ b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/List.java @@ -6,4 +6,5 @@ public interface List { public Object get(int index); public Object remove(int index); public int size(); + public Iterator iterator(); } diff --git a/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java b/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java index 06efea8aa0..baca03b06b 100644 --- a/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java +++ b/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java @@ -1,16 +1,173 @@ package com.coding.basic; +import org.junit.Assert; import org.junit.Test; -import static org.junit.Assert.*; - /** * Created by luoziyihao on 3/23/17. */ public class LinkedListTest { + + @Test + public void add() throws Exception { + + } + + @Test + public void add1() throws Exception { + + } + + @Test + public void get() throws Exception { + + } + + @Test + public void remove() throws Exception { + + } + + @Test + public void size() throws Exception { + + } + + @Test + public void addFirst() throws Exception { + + } + + @Test + public void addLast() throws Exception { + + } + + @Test + public void removeFirst() throws Exception { + + } + + @Test + public void removeLast() throws Exception { + + } + + @Test + public void removeFirstHalf() throws Exception { + LinkedList linkedList = createAndFillLinkedList(0); + linkedList.removeFirstHalf(); + Assert.assertEquals("[]", linkedList.toString()); + } + @Test + public void removeFirstHalf1() throws Exception { + LinkedList linkedList = createAndFillLinkedList(1); + linkedList.removeFirstHalf(); + Assert.assertEquals("[1]", linkedList.toString()); + } + @Test + public void removeFirstHalf2() throws Exception { + LinkedList linkedList = createAndFillLinkedList(2); + linkedList.removeFirstHalf(); + Assert.assertEquals("[2]", linkedList.toString()); + } + @Test + public void removeFirstHalf3() throws Exception { + LinkedList linkedList = createAndFillLinkedList(3); + linkedList.removeFirstHalf(); + Assert.assertEquals("[2,3]", linkedList.toString()); + } + + private LinkedList createAndFillLinkedList() { + return createAndFillLinkedList(4); + } + + private LinkedList createAndFillLinkedList(int length) { + + LinkedList linkedList = new LinkedList(); + for (int i = 1; i <= length; i++) { + linkedList.add(i); + } + return linkedList; + } + + @Test + public void remove1() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(0, 0); + Assert.assertEquals("[1,2,3,4]", list.toString()); + } + @Test + public void remove2() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(0, 1); + Assert.assertEquals("[2,3,4]", list.toString()); + } + @Test + public void remove3() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(1, 0); + Assert.assertEquals("[1,2,3,4]", list.toString()); + } + @Test + public void remove4() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(1, 1); + Assert.assertEquals("[1,3,4]", list.toString()); + } +@Test + public void remove5() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(1, 3); + Assert.assertEquals("[1]", list.toString()); + } +@Test + public void remove6() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(1, 4); + Assert.assertEquals("[1]", list.toString()); + } +@Test + public void remove7() throws Exception { + LinkedList list = createAndFillLinkedList(4); + list.remove(1, 5); + Assert.assertEquals("[1]", list.toString()); + } + + @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 public void iterator() throws Exception { + List linkedList = new LinkedList(); + linkedList.add("1"); + linkedList.add("2"); + linkedList.add("3"); + linkedList.add("4"); + Assert.assertEquals("[1,2,3,4]", linkedList.toString()); } @Test @@ -21,7 +178,7 @@ public void reverse() throws Exception { linkedList.add("3"); linkedList.add("4"); linkedList.reverse(); - System.out.println(linkedList); + Assert.assertEquals("[4,3,2,1]", linkedList.toString()); } } \ No newline at end of file diff --git a/group22/1158477486/src/TestCollection/ArrayUtil.java b/group22/1158477486/src/TestCollection/ArrayUtil.java new file mode 100644 index 0000000000..e66decc220 --- /dev/null +++ b/group22/1158477486/src/TestCollection/ArrayUtil.java @@ -0,0 +1,259 @@ +package TestCollection; +import java.util.ArrayList; + + +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){ + + for(int i=0,j=origin.length-1;i array[j] ) // ˳ˣͽһ + { + swap = array[j]; + array[j] = array[j-1]; + array[j-1] = swap; + } + } + } + + return array; + } + /** + * һѾݵ 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){ + int newArray[]=new int [oldArray.length+size]; + System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); + return newArray; + } + + + /** + * 쳲Ϊ1123581321...... һֵ Сڸֵ + * 磬 max = 15 , 򷵻صӦΪ [11235813] + * max = 1, 򷵻ؿ [] + * @param max + * @return + */ + public int[] fibonacci(int max){ + int[] a=new int [100]; + a[0]=1; + a[1]=1; + int i =2; + for(;ilist=new ArrayList(); + for (int i = 2; i list1=new ArrayList(); + ArrayListlist=new ArrayList(); + for(int i=1;i parameters) { + + View view = new View(); + /* + 0. ȡļstruts.xml + 1. actionNameҵӦclass LoginAction, ͨʵ + parametersеݣösetter parametersе + ("name"="test" , "password"="1234") , + ǾӦõ setNamesetPassword + 2. ͨöexectue ÷ֵ"success" + 3. ͨҵgetter getMessage, + ͨã ֵγһHashMap , {"message": "¼ɹ"} , + ŵViewparameters + ŵViewjspֶС + */ + + SAXReader reader = new SAXReader(); + Document document = null; + try { + document = reader.read("src/struts.xml"); + } catch (DocumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Element root= document.getRootElement(); + List list = root.elements("action"); + String className = null; + Element newElement = null; + for (Element element : list) { + if(element.attribute("name").getValue().equals(actionName)){ + Attribute attribute = element.attribute("class"); + newElement = element; + className = attribute.getValue(); + } + } + Class clazz = null; + try { + clazz = Class.forName(className); + Object obj = clazz.newInstance(); + for (String key : parameters.keySet()) + { + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + if(method.getName().toLowerCase().equals(("set"+key).toLowerCase())){ + method.invoke(obj,parameters.get(key)); + } + } + + } + + String value = (String) clazz.getMethod("execute").invoke(obj); + List elements = newElement.elements(); + + String message = ""; + String jsp = ""; + for (Element element : elements) { + if(element.attribute("name").getValue().equals(value)){ + jsp = element.getText(); + } + } + if("success".equals(value)){ + message = "login successful"; + }else if("fail".equals(value)){ + message = "login failed,please check your user/pwd"; + } + view.setJsp(jsp); + Map p = new HashMap(); + p.put("message",message); + view.setParameters(p); + + return view; + + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return view; + } +} \ No newline at end of file diff --git a/group22/1158477486/src/TestCollection/StrutsTest.java b/group22/1158477486/src/TestCollection/StrutsTest.java new file mode 100644 index 0000000000..67e45530c5 --- /dev/null +++ b/group22/1158477486/src/TestCollection/StrutsTest.java @@ -0,0 +1,51 @@ +package TestCollection; + +import java.util.HashMap; +import java.util.Map; + +import org.dom4j.DocumentException; +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() throws DocumentException { + + String actionName = "login"; + + Map params = new HashMap(); + + params.put("name","test"); + + params.put("password","123456"); //ԤIJһ + 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/group22/1158477486/src/TestCollection/View.java b/group22/1158477486/src/TestCollection/View.java new file mode 100644 index 0000000000..1b52dd7b0e --- /dev/null +++ b/group22/1158477486/src/TestCollection/View.java @@ -0,0 +1,43 @@ +package TestCollection; + +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; + + } + +} \ No newline at end of file diff --git a/group22/1158477486/src/TestCollection/struts.xml b/group22/1158477486/src/TestCollection/struts.xml new file mode 100644 index 0000000000..f7e08e609d --- /dev/null +++ b/group22/1158477486/src/TestCollection/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/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedList.java b/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedList.java index 1dc4dd4342..dbca3e4361 100644 --- a/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedList.java +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedList.java @@ -73,7 +73,7 @@ public Object remove(int index) { Node lastNode = null; if (index + 1 <= size - 1) //判断是否有下一位 nextNode = findNode(index + 1); - if (index - 1 > 0) //判断是否有上一位 + if (index - 1 >= 0) //判断是否有上一位 lastNode = findNode(index - 1); if (lastNode == null) { head = nextNode; @@ -172,17 +172,17 @@ public Object next() { } /** - * 鎶婅閾捐〃閫嗙疆 - * 渚嬪閾捐〃涓�3->7->10 , 閫嗙疆鍚庡彉涓� 10->7->3 + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ } /** - * 鍒犻櫎涓�釜鍗曢摼琛ㄧ殑鍓嶅崐閮ㄥ垎 - * 渚嬪锛歭ist = 2->5->7->8 , 鍒犻櫎浠ュ悗鐨勫�涓�7->8 - * 濡傛灉list = 2->5->7->8->10 ,鍒犻櫎浠ュ悗鐨勫�涓�,8,10 + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf(){ @@ -190,7 +190,7 @@ public void removeFirstHalf(){ } /** - * 浠庣i涓厓绱犲紑濮嬶紝 鍒犻櫎length 涓厓绱�锛�娉ㄦ剰i浠�寮� + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * @param i * @param length */ @@ -198,11 +198,11 @@ public void remove(int i, int length){ } /** - * 鍋囧畾褰撳墠閾捐〃鍜宭ist鍧囧寘鍚凡鍗囧簭鎺掑垪鐨勬暣鏁� - * 浠庡綋鍓嶉摼琛ㄤ腑鍙栧嚭閭d簺list鎵�寚瀹氱殑鍏冪礌 - * 渚嬪褰撳墠閾捐〃 = 11->101->201->301->401->501->601->701 + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 * listB = 1->3->4->6 - * 杩斿洖鐨勭粨鏋滃簲璇ユ槸[101,301,401,601] + * 返回的结果应该是[101,301,401,601] * @param list */ public static int[] getElements(LinkedList list){ @@ -210,8 +210,8 @@ public static int[] getElements(LinkedList list){ } /** - * 宸茬煡閾捐〃涓殑鍏冪礌浠ュ�閫掑鏈夊簭鎺掑垪锛屽苟浠ュ崟閾捐〃浣滃瓨鍌ㄧ粨鏋勩� - * 浠庡綋鍓嶉摼琛ㄤ腑涓垹闄ゅ湪list涓嚭鐜扮殑鍏冪礌 + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 * @param list */ @@ -221,16 +221,16 @@ public void subtract(LinkedList list){ } /** - * 宸茬煡褰撳墠閾捐〃涓殑鍏冪礌浠ュ�閫掑鏈夊簭鎺掑垪锛屽苟浠ュ崟閾捐〃浣滃瓨鍌ㄧ粨鏋勩� - * 鍒犻櫎琛ㄤ腑鎵�湁鍊肩浉鍚岀殑澶氫綑鍏冪礌锛堜娇寰楁搷浣滃悗鐨勭嚎鎬ц〃涓墍鏈夊厓绱犵殑鍊煎潎涓嶇浉鍚岋級 + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ } /** - * 宸茬煡閾捐〃涓殑鍏冪礌浠ュ�閫掑鏈夊簭鎺掑垪锛屽苟浠ュ崟閾捐〃浣滃瓨鍌ㄧ粨鏋勩� - * 璇曞啓涓�珮鏁堢殑绠楁硶锛屽垹闄よ〃涓墍鏈夊�澶т簬min涓斿皬浜巑ax鐨勫厓绱狅紙鑻ヨ〃涓瓨鍦ㄨ繖鏍风殑鍏冪礌锛� + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * @param min * @param max */ @@ -239,12 +239,11 @@ public void removeRange(int min, int max){ } /** - * 鍋囪褰撳墠閾捐〃鍜屽弬鏁發ist鎸囧畾鐨勯摼琛ㄥ潎浠ュ厓绱犱緷鍊奸�澧炴湁搴忔帓鍒楋紙鍚屼竴琛ㄤ腑鐨勫厓绱犲�鍚勪笉鐩稿悓锛� - * 鐜拌姹傜敓鎴愭柊閾捐〃C锛屽叾鍏冪礌涓哄綋鍓嶉摼琛ㄥ拰list涓厓绱犵殑浜ら泦锛屼笖琛–涓殑鍏冪礌鏈変緷鍊奸�澧炴湁搴忔帓鍒� + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ public LinkedList intersection( LinkedList list){ return null; } - } diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedListTest.java b/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedListTest.java index 254aa95c53..c566888cdf 100644 --- a/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedListTest.java +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/first/LinkedListTest.java @@ -65,7 +65,7 @@ public void testGet() { @Test public void testRemoveInt() { - LinkedList li = new LinkedList(); + /*LinkedList li = new LinkedList(); li.add("1"); li.add("2"); li.add("3"); @@ -75,8 +75,23 @@ public void testRemoveInt() { assertEquals(li.get(0), "1"); assertEquals(li.get(1), "2"); assertEquals(li.get(2), "3"); - assertEquals(li.get(3), "5"); + assertEquals(li.get(3), "5");*/ + LinkedList ll = new LinkedList(); + ll.add(11); + ll.add(101); + ll.add(201); + ll.add(301); + ll.add(401); + ll.add(501); + ll.add(601); + ll.add(701); + ll.remove(0); + ll.remove(1); + //ll.remove(3); + //ll.remove(4); + System.out.println(ll.get(0)+" "+ll.get(1)+" "+ll.get(2)+" "+ll.get(3)); + } @Test diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/DownloadThread.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/DownloadThread.java new file mode 100644 index 0000000000..f59f585528 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/DownloadThread.java @@ -0,0 +1,43 @@ +package com.github.mrwengq.tid; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.github.mrwengq.tid.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String fileName; + CyclicBarrier cb; + + public DownloadThread( Connection conn, String fileName ,int startPos, int endPos,CyclicBarrier cb){ + + this.conn = conn; + this.fileName = fileName; + this.startPos = startPos; + this.endPos = endPos; + this.cb = cb; + } + public void run(){ + byte[] b = null; + try { + b = conn.read(startPos,endPos); + RandomAccessFile raf = new RandomAccessFile(fileName, "rw"); + raf.seek(startPos); + raf.write(b); + raf.close(); + conn.close(); + cb.await(); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloader.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloader.java new file mode 100644 index 0000000000..21de21e939 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloader.java @@ -0,0 +1,129 @@ +package com.github.mrwengq.tid; + +import java.io.FileNotFoundException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.github.mrwengq.tid.api.Connection; +import com.github.mrwengq.tid.api.ConnectionException; +import com.github.mrwengq.tid.api.ConnectionManager; +import com.github.mrwengq.tid.api.DownloadListener; + + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + String fileName; + + public FileDownloader(String _url,String fileName) { + this.url = _url; + this.fileName = fileName; + + } + + 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; + + CyclicBarrier cb = new CyclicBarrier(3, new Runnable() { + + @Override + public void run() { + listener.notifyFinished(); + + } + }); + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + System.out.println(length); + createFile(length); //创建占位文件 + + int size = length/3; + int pyl = (length - (length%3))/3; + + if(length<3){ + + cb = new CyclicBarrier(3, new Runnable() { + @Override + public void run() { + listener.notifyFinished(); + } + }); + new DownloadThread(conn,fileName,0,length-1,cb).start(); + + + }else{ + + for(int i =0;i<3;i++){ + if(2==i){ + new DownloadThread(conn,fileName, i*size, (i+1)*size+length%3-1,cb).start(); + System.out.println("第i线程"+i+"起始"+i*size+"-结束"+(i*size+length%3-1)); + break; + } + + new DownloadThread(conn,fileName,i*size,(i+1)*size-1,cb).start(); + System.out.println("第i线程"+i+"起始"+i*size+"-结束"+((i+1)*size-1)); + } + + } + } 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; + } + private void createFile( int length){ + try { + RandomAccessFile raf = new RandomAccessFile(fileName,"rw"); + while(length>0){ + raf.write(0); + length --; + } + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloaderTest.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloaderTest.java new file mode 100644 index 0000000000..da68d5031f --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloaderTest.java @@ -0,0 +1,60 @@ +package com.github.mrwengq.tid; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.mrwengq.tid.api.ConnectionManager; +import com.github.mrwengq.tid.api.DownloadListener; +import com.github.mrwengq.tid.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://localhost:8080/test.jpg"; + String url = "http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + String fileName = "C:\\Users\\Administrator\\Desktop\\个人文档\\test.jpg"; + FileDownloader downloader = new FileDownloader(url,fileName); + + + 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/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/Connection.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/Connection.java new file mode 100644 index 0000000000..e92c3796ca --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/Connection.java @@ -0,0 +1,23 @@ +package com.github.mrwengq.tid.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/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionException.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionException.java new file mode 100644 index 0000000000..ce3b3a66c9 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.github.mrwengq.tid.api; + +public class ConnectionException extends Exception { + +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionManager.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionManager.java new file mode 100644 index 0000000000..2112030d07 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.github.mrwengq.tid.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/DownloadListener.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/DownloadListener.java new file mode 100644 index 0000000000..97f89fef60 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.github.mrwengq.tid.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionImpl.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionImpl.java new file mode 100644 index 0000000000..52f8d0f5c1 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionImpl.java @@ -0,0 +1,72 @@ +package com.github.mrwengq.tid.impl; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; + +import com.github.mrwengq.tid.api.Connection; + +public class ConnectionImpl implements Connection{ + + private URL url; + + public ConnectionImpl(String url ){ + try { + this.url = new URL(url); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + URLConnection con = url.openConnection(); + con.setRequestProperty("RANGE","bytes="+startPos+"-"+endPos); + BufferedInputStream bf = new BufferedInputStream(con.getInputStream()); + byte[] b = new byte[1024]; + int tolen = endPos - startPos +1; + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + while(bo.size()tolen){ + byte[] data = bo.toByteArray(); + return Arrays.copyOf(data, tolen); + } + return bo.toByteArray(); + } + + @Override + public int getContentLength() { + int a = 0; + try { + + URLConnection con = url.openConnection(); + a = con.getContentLength(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return a; + } + + @Override + public void close() { + + + } + + +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionManagerImpl.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..62e0b3e6e0 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionManagerImpl.java @@ -0,0 +1,21 @@ +package com.github.mrwengq.tid.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + + +import com.github.mrwengq.tid.api.Connection; +import com.github.mrwengq.tid.api.ConnectionException; +import com.github.mrwengq.tid.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/Iterator.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/Iterator.java new file mode 100644 index 0000000000..3dd2a731f0 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/Iterator.java @@ -0,0 +1,10 @@ +package com.github.mrwengq.tid.list; + + +public interface Iterator +{ + + public abstract boolean hasNext(); + + public abstract Object next(); +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedList.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedList.java new file mode 100644 index 0000000000..77b0b0ca2b --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedList.java @@ -0,0 +1,401 @@ +package com.github.mrwengq.tid.list; + +public class LinkedList implements List { + private Node head; + private int size =0; + private static class Node { + + Object data; + Node next; + + public Node(Object o) { + data = o; + next = null; + } + } + + + public void add(Object o) { + if (size == 0) { + head = new Node(o); + } else { + Node node = new Node(o); + Node lastNode = findNode(size-1); + lastNode.next = node; + } + size++; + } + + private Node findNode(int index) {//用于查找节点 + Node no = head; + for (; index > 0; index--) + no = no.next; + + return no; + } + + public void add(int index, Object o) { + if (index < 0 || index > size - 1) + throw new ArrayIndexOutOfBoundsException(); + Node node = new Node(o); + Node indexNode = findNode(index); + if (index - 1 < 0) { + node.next = indexNode; + head = node; + size++; + return; + } else { + Node lastNode = findNode(index - 1); + lastNode.next = node; + node.next = indexNode; + size++; + return; + } + } + + public Object get(int index) { + if (index < 0 || index > size - 1) + throw new ArrayIndexOutOfBoundsException(); + else + return findNode(index).data; + } + + public Object remove(int index) { + if (index < 0 || index > size - 1 || size == 0) + throw new ArrayIndexOutOfBoundsException(); + Node indexNode = findNode(index); + if (size == 1) { + head = null; + size = 0; + return indexNode.data; + } + Node nextNode = null; + Node lastNode = null; + if (index + 1 <= size - 1) //判断是否有下一位 + nextNode = findNode(index + 1); + if (index - 1 >= 0) //判断是否有上一位 + lastNode = findNode(index - 1); + if (lastNode == null) { + head = nextNode; + size--; + return indexNode.data; + }else if (nextNode == null) { + lastNode.next = null; + size--; + return indexNode.data; + } else { + lastNode.next = nextNode; + size--; + return indexNode.data; + } + } + + public int size() { + return size; + } + + public void addFirst(Object o) { + Node node = new Node(o); + if (size == 0) { + head = node; + size++; + return; + } else { + node.next = head; + head = node; + size++; + return; + } + } + + public void addLast(Object o) { + Node node = new Node(o); + if (size == 0) { + head = node; + size++; + return; + } else { + Node lastNode = findNode(size-1); + lastNode.next = node; + size++; + return; + } + } + + public Object removeFirst() { + if (size == 0) { + return null; + } else { + Node nextNode = head.next; + Object ob = head.data; + head = nextNode; + size--; + return ob; + } + } + + public Object removeLast() { + if (size == 0) { + return null; + } else { + Node node = findNode(size-1); //size -1 为最后一位 -2为前一位 + if(size-2>=0){ + Node lastNode = findNode(size - 2); + lastNode.next = null; + } + size--; + return node.data; + } + } + + public Iterator iterator() { + return new Iterator() { + + int index = -1; + + public boolean hasNext() { + index++; + if(index7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(size==0){ + throw new RuntimeException(); + } + int cs = size/2; + int endIndex = size -1; + for(int i = 0;i5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(size<2){ + throw new RuntimeException(); + } + + int len = size/2; + Node node = findNode(len-1);//len-1为删除链表的最后一位下标 + for( int j = len-2; j>=0 ; j--){ + Node temp = findNode(j); + temp.next = null; + } + head = node.next; + node.next = null; + size -= len; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(0 == size||i > size-1){ + throw new RuntimeException(); + } + Node beforNode = findNode(i-1); //i的前一个元素 + Node afterNode = findNode(i+length);//被删除最大下标节点的下一个节点 + for( int j = i+length-1; j101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int temp = list.size()-1; + if(temp>size){ + throw new RuntimeException(); + } + int[] b = new int[list.size()]; + for(int i = 0;i0){ + for (; temp > 0; temp--) + no = no.next; + } + b[i] = (int)no.data; + } + return b; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + if(list==null){ + throw new RuntimeException(); + } + for(int i = 0;i min){ + lmax = lmid-1; + if((int)this.get(lmax)min){ + rmin = lmin; + break; + } + } + } + while(lminmax){ + rmax = lmid; + } + }else if((int)this.get(lmid)>=max){ + lmax = lmid -1; + if((int)this.get(lmax)=rmin;i--){ + Node removeNode = findNode(i); + removeNode.next = null; + size--; + } + beforNode.next = afterNode; + } + + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + int len = size; + int llen = list.size(); + int i = 0; + int j = 0; + LinkedList ll= new LinkedList(); + while(true){ + if(i == len &&j == llen ){ + break; + } + if(i>len-1){ + ll.add(list.get(j++)); + continue; + } + if(j>llen-1){ + ll.add(this.get(i++)); + continue; + } + if((int)get(i)<(int)list.get(j)){ + ll.add(this.get(i++)); + }else if((int)get(i)>(int)list.get(j)){ + ll.add(list.get(j++)); + }else{ + ll.add(list.get(j++)); + i++; + } + } + return ll; + } +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedListTest.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedListTest.java new file mode 100644 index 0000000000..91fe49652a --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedListTest.java @@ -0,0 +1,176 @@ +package com.github.mrwengq.tid.list; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class LinkedListTest { + + LinkedList ll = null; + + @Before + public void setUp() throws Exception { + ll = new LinkedList(); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testReverse() { + ll.add(3); + ll.add(7); + ll.add(10); + ll.add(6); + ll.add(12); + assertEquals((int)ll.get(0), 3); + assertEquals((int)ll.get(1), 7); + assertEquals((int)ll.get(2), 10); + assertEquals((int)ll.get(3), 6); + assertEquals((int)ll.get(4), 12); + ll.reverse(); + assertEquals((int)ll.get(0), 12); + assertEquals((int)ll.get(1), 6); + assertEquals((int)ll.get(2), 10); + assertEquals((int)ll.get(3), 7); + assertEquals((int)ll.get(4), 3); + + } + + @Test + public void testRemoveFirstHalf() { + ll.add(2); + ll.add(5); + ll.add(7); + ll.add(8); + ll.add(10); + assertEquals((int)ll.get(0), 2); + assertEquals((int)ll.get(1), 5); + assertEquals((int)ll.get(2), 7); + assertEquals((int)ll.get(3), 8); + assertEquals((int)ll.get(4), 10); + assertEquals(ll.size(),5); + ll.removeFirstHalf(); + assertEquals((int)ll.get(0), 7); + assertEquals((int)ll.get(1), 8); + assertEquals((int)ll.get(2), 10); + assertEquals(ll.size(),3); + } + + @Test + public void testRemoveIntInt() { + ll.add(2); + ll.add(5); + ll.add(7); + ll.add(8); + ll.add(10); + assertEquals(ll.size(),5); + ll.remove(1, 2); + assertEquals((int)ll.get(0), 2); + assertEquals((int)ll.get(1), 8); + assertEquals((int)ll.get(2), 10); + assertEquals(ll.size(),3); + } + + @Test + public void testGetElements() { + LinkedList list = new LinkedList(); + list.add(1); + list.add(3); + list.add(4); + list.add(6); + assertEquals(list.size(),4); + ll.add(11); + ll.add(101); + ll.add(201); + ll.add(301); + ll.add(401); + ll.add(501); + ll.add(601); + ll.add(701); + int [] b = ll.getElements(list); + assertArrayEquals(new int[]{101,301,401,601}, b); + } + + @Test + public void testSubtract() { + ll.add(11); + ll.add(101); + ll.add(201); + ll.add(301); + ll.add(401); + ll.add(501); + ll.add(601); + ll.add(701); + LinkedList list = new LinkedList(); + list.add(11); + list.add(201); + list.add(301); + list.add(401); + ll.subtract(list); + assertEquals(list.size(),4); + assertEquals((int)ll.get(0), 101); + assertEquals((int)ll.get(1), 501); + assertEquals((int)ll.get(2), 601); + assertEquals((int)ll.get(3), 701); + } + + @Test + public void testRemoveDuplicateValues() { + ll.add(11); + ll.add(101); + ll.add(101); + ll.add(101); + ll.add(401); + ll.add(501); + ll.add(501); + ll.add(701); + ll.removeDuplicateValues(); + assertEquals((int)ll.get(0), 11); + assertEquals((int)ll.get(1), 101); + assertEquals((int)ll.get(2), 401); + assertEquals((int)ll.get(3), 501); + assertEquals((int)ll.get(4), 701); + + } + + @Test + public void testRemoveRange() { + ll.add(11); + ll.add(101); + ll.add(201); + ll.add(301); + ll.add(401); + ll.add(501); + ll.add(601); + ll.add(701); + ll.removeRange(400, 700); + assertEquals(ll.size(),5); + + } + + @Test + public void testIntersection() { + ll.add(11); + ll.add(101); + ll.add(201); + + LinkedList list = new LinkedList(); + list.add(101); + list.add(121); + list.add(300); + ll = ll.intersection(list); + + assertEquals(ll.size(), 5); + assertEquals((int)ll.get(0), 11); + assertEquals((int)ll.get(1), 101); + assertEquals((int)ll.get(2), 121); + assertEquals((int)ll.get(3), 201); + assertEquals((int)ll.get(4), 300); + + } + +} diff --git a/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/List.java b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/List.java new file mode 100644 index 0000000000..eaf561cb97 --- /dev/null +++ b/group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/List.java @@ -0,0 +1,16 @@ +package com.github.mrwengq.tid.list; + + +public interface List +{ + + public abstract void add(Object obj); + + public abstract void add(int i, Object obj); + + public abstract Object get(int i); + + public abstract Object remove(int i); + + public abstract int size(); +} diff --git a/group22/1258890344/src/com/coderising/download/DownloadThread.java b/group22/1258890344/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..af605fc3e3 --- /dev/null +++ b/group22/1258890344/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,31 @@ +package com.coderising.download; + +import java.io.File; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + File file; + + public DownloadThread( Connection conn, int startPos, int endPos,File file){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.file=file; + } + + public void run(){ + try { + conn.read(startPos, endPos,file); +// conn.close(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/group22/1258890344/src/com/coderising/download/FileDownloader.java b/group22/1258890344/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..f0bebf1623 --- /dev/null +++ b/group22/1258890344/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,105 @@ +package com.coderising.download; + +import java.io.File; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + + +public class FileDownloader { + + String url; + String path; + int threadNum;//线程数 + int fileLength;//要下载的文件的大小 + File file; + + DownloadListener listener; + + ConnectionManager cm; + + public FileDownloader(){ + + } + public FileDownloader(String _url,String _path,int _threadNum) { + this.url = _url; + this.path=_path; + this.threadNum=_threadNum; + } + + + 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=new File(path); + if(!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + if(file.exists()){ + file.delete(); + } + file.createNewFile();//创建 文件 + + + fileLength = conn.getContentLength();//获取要下载的文件的大小 + System.out.println("文件总长度:"+fileLength+"字节"); + + int blockSize=fileLength/threadNum; //每个线程平均下载的块的大小 + + for(int i=1;i<=threadNum;i++){ + int startPos=(i-1)*blockSize; + int endPos=i*blockSize-1; + if(i==threadNum){ + endPos=fileLength; + } + System.out.println("线程"+i+"下载"+startPos+"字节~"+endPos+"字节"); + + new Thread(new DownloadThread(conn,startPos,endPos,file)).start(); + + } + + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + while(file.length()7->10 , 逆置后变为 10->7->3 */ - public void reverse(){ - + public void reverse(){ + for(int i=0;i<(size/2);i++){ + Object data1=get(i); + Object data2=get(size-1); + Object object=data1; + data1=data2; + data2=object; + } } /** @@ -140,7 +146,9 @@ public void reverse(){ */ public void removeFirstHalf(){ - + for(int i=0;i<(size/2);i++){ + remove(i); + } } /** @@ -149,7 +157,9 @@ public void removeFirstHalf(){ * @param length */ public void remove(int i, int length){ - + for(int j=i;j<(i+length);j++){ + remove(j); + } } /** * 假定当前链表和list均包含已升序排列的整数 @@ -159,7 +169,12 @@ public void remove(int i, int length){ * 返回的结果应该是[101,301,401,601] * @param list */ - public static int[] getElements(LinkedList list){ + public int[] getElements(LinkedList list){ + int[] array=new int[list.size]; + int i=0; + for(Node head=list.head;head!=null;head=head.next){ + array[i]=(int) this.get((int)head.data); + } return null; } @@ -171,7 +186,7 @@ public static int[] getElements(LinkedList list){ */ public void subtract(LinkedList list){ - + } /** @@ -198,6 +213,7 @@ public void removeRange(int min, int max){ * @param list */ public LinkedList intersection( LinkedList list){ + return null; } } diff --git a/group22/1335499238/coding2017/src/main/java/com/coderising/download/DownloadThread.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..3e2206ea65 --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/DownloadThread.java @@ -0,0 +1,35 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CountDownLatch; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + CountDownLatch cdl; + + public DownloadThread( Connection conn, int startPos, int endPos, CountDownLatch cdl){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.cdl = cdl; + } + public void run(){ + try { + byte[] read = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile("F:\\test.rar", "rwd"); + raf.seek(startPos); + raf.write(read); + raf.close(); + cdl.countDown(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloader.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..bdb15ffcc9 --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloader.java @@ -0,0 +1,81 @@ +package com.coderising.download; + +import java.util.concurrent.CountDownLatch; + +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 { + + public static final int THREAD_NUM = 5; + + 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; + CountDownLatch cdl = new CountDownLatch(THREAD_NUM); + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + int averageLength = length/THREAD_NUM; + for (int i = 0; i < THREAD_NUM; i++) { + if(i == THREAD_NUM - 1){ + new DownloadThread(conn,averageLength * i,length-1,cdl).start(); + }else{ + new DownloadThread(conn,averageLength * i,averageLength * (i + 1) - 1,cdl).start(); + } + } + try { + cdl.await(); + listener.notifyFinished(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } 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/group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloaderTest.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..1e07568b28 --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,53 @@ +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://127.0.0.1:8020/demo/java.rar"; + + 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/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/Connection.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..9710e270e1 --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/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/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionException.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..8dbfe95dda --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionManager.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..fb44ede457 --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/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/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/DownloadListener.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..4cd0b3eab1 --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionImpl.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..a218bc4feb --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,51 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + + +public class ConnectionImpl implements Connection{ + + private URLConnection urlConnection; + private URL url; + public ConnectionImpl(String url){ + try { + this.url = new URL(url); + urlConnection = this.url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + URLConnection uc = url.openConnection(); + uc.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream inputStream = uc.getInputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length = 0; + while((length = inputStream.read(buffer)) != -1){ + baos.write(buffer, 0, length); + } + inputStream.close(); + baos.close(); + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + return urlConnection.getContentLength(); + } + + @Override + public void close() { + + } + +} diff --git a/group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..2d6768697e --- /dev/null +++ b/group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.coderising.download.impl; + +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/group22/1335499238/week01/src/basic/ArrayList.java b/group22/1335499238/week01/src/basic/ArrayList.java index 64b3045312..5e099a6c72 100644 --- a/group22/1335499238/week01/src/basic/ArrayList.java +++ b/group22/1335499238/week01/src/basic/ArrayList.java @@ -18,7 +18,7 @@ public ArrayList(int capacity){ }else if(capacity == 0){ }else{ - new IllegalArgumentException("initsize:"+capacity); + throw new IllegalArgumentException("initsize:"+capacity); } } @@ -39,13 +39,13 @@ public void add(int index, Object o) { @Override public Object get(int index) { - checkIndex(index); + checkIndex(index + 1); return elementData[index]; } @Override public Object remove(int index) { - checkIndex(index); + checkIndex(index + 1); Object removeparam = elementData[index]; int numMoved = size - index - 1; if(numMoved > 0){ diff --git a/group22/1335499238/week01/src/basic/LinkedList.java b/group22/1335499238/week01/src/basic/LinkedList.java index 9af1471bfb..5e20329a2e 100644 --- a/group22/1335499238/week01/src/basic/LinkedList.java +++ b/group22/1335499238/week01/src/basic/LinkedList.java @@ -28,14 +28,14 @@ public void add(int index, Object o) { @Override public Object get(int index) { - checkIndex(index); + checkIndex(index + 1); return findByIndex(index).data; } @Override public Object remove(int index) { Node remove = null; - checkIndex(index); + checkIndex(index + 1); Node next = findByIndex(index+1); if(index == 0){ remove = head; @@ -135,7 +135,12 @@ private void checkIndex(int index){ * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ - + Node current = this.head; + for (int i = 0; i < size-1; i++) { + removeFirst(); + add(size - i, current.data); + current = current.next; + } } /** @@ -145,7 +150,10 @@ public void reverse(){ * */ public void removeFirstHalf(){ - + int total = size/2; + for (int i = 0; i < total; i++) { + removeFirst(); + } } /** @@ -154,7 +162,15 @@ public void removeFirstHalf(){ * @param length */ public void remove(int i, int length){ - + if(i < 0 || length < 0){ + throw new IllegalArgumentException("参数异常"); + } + if(i + length > size){ + throw new IndexOutOfBoundsException(); + } + for (int j = 0; j < length; j++) { + remove(i); + } } /** * 假定当前链表和listB均包含已升序排列的整数 @@ -165,7 +181,20 @@ public void remove(int i, int length){ * @param list */ public int[] getElements(LinkedList list){ - return null; + if(list == null || list.head == null){ + return new int[0]; + } + int result[] = new int [list.size]; + Iterator iterator = list.iterator(); + int index = 0; + while(iterator.hasNext()){ + int next = (int)iterator.next(); + if(next < size){ + result[index] = (int)this.get(next); + } + index++; + } + return result; } /** @@ -175,14 +204,33 @@ public int[] getElements(LinkedList list){ */ public void subtract(LinkedList list){ - + if(list == null || list.head == null){ + return; + } + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + Object next = iterator.next(); + Iterator iteratorInner = this.iterator(); + int index = 0; + while(iteratorInner.hasNext()){ + if(next.equals(iteratorInner.next())){ + this.remove(index); + break; + } + index++; + } + } } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ - + for (int i = 0; i < size; i++) { + if(findByIndex(i).data == findByIndex(i+1).data){ + remove(i); + } + } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 @@ -191,7 +239,25 @@ public void removeDuplicateValues(){ * @param max */ public void removeRange(int min, int max){ - + if(min >= max){ + throw new IllegalArgumentException("参数异常"); + } + int minIndex = 0; + int maxIndex = 0; + boolean flag = true; + for (int i = 0; i < size; i++) { + int current = (int)get(i); + if(flag && current > min){ + minIndex = i; + flag = false; + }else if(current >= max){ + maxIndex = i; + break; + }else{ + maxIndex = size; + } + } + remove(minIndex, maxIndex - minIndex); } /** @@ -200,7 +266,20 @@ public void removeRange(int min, int max){ * @param list */ public LinkedList intersection( LinkedList list){ - return null; + if(list == null || list.head == null){ + return null; + } + LinkedList linkedList = new LinkedList(); + Iterator iterator = this.iterator(); + while(iterator.hasNext()){ + Object next = iterator.next(); + Iterator iterator2 = list.iterator(); + while(iterator2.hasNext()){ + if(next.equals(iterator2.next())){ + linkedList.add(next); + } + } + } + return linkedList; } - } diff --git a/group22/17457741/src/thirdwork/DownloadThread.java b/group22/17457741/src/thirdwork/DownloadThread.java new file mode 100644 index 0000000000..310758592b --- /dev/null +++ b/group22/17457741/src/thirdwork/DownloadThread.java @@ -0,0 +1,5 @@ +package thirdwork; + +public class DownloadThread { + +} diff --git a/group22/17457741/src/thirdwork/FileDownloader.java b/group22/17457741/src/thirdwork/FileDownloader.java new file mode 100644 index 0000000000..11746c405f --- /dev/null +++ b/group22/17457741/src/thirdwork/FileDownloader.java @@ -0,0 +1,5 @@ +package thirdwork; + +public class FileDownloader { + +} diff --git a/group22/17457741/src/thirdwork/api/Connection.java b/group22/17457741/src/thirdwork/api/Connection.java new file mode 100644 index 0000000000..5086fe7662 --- /dev/null +++ b/group22/17457741/src/thirdwork/api/Connection.java @@ -0,0 +1,5 @@ +package thirdwork.api; + +public class Connection { + +} diff --git a/group22/17457741/src/thirdwork/api/ConnectionException.java b/group22/17457741/src/thirdwork/api/ConnectionException.java new file mode 100644 index 0000000000..c7a4b0e30d --- /dev/null +++ b/group22/17457741/src/thirdwork/api/ConnectionException.java @@ -0,0 +1,5 @@ +package thirdwork.api; + +public class ConnectionException { + +} diff --git a/group22/17457741/src/thirdwork/api/ConnectionManager.java b/group22/17457741/src/thirdwork/api/ConnectionManager.java new file mode 100644 index 0000000000..f0c043d484 --- /dev/null +++ b/group22/17457741/src/thirdwork/api/ConnectionManager.java @@ -0,0 +1,5 @@ +package thirdwork.api; + +public class ConnectionManager { + +} diff --git a/group22/17457741/src/thirdwork/api/DownloadListener.java b/group22/17457741/src/thirdwork/api/DownloadListener.java new file mode 100644 index 0000000000..40f6cdf0ac --- /dev/null +++ b/group22/17457741/src/thirdwork/api/DownloadListener.java @@ -0,0 +1,5 @@ +package thirdwork.api; + +public class DownloadListener { + +} diff --git a/group22/17457741/src/thirdwork/impl/ConnectionImpl.java b/group22/17457741/src/thirdwork/impl/ConnectionImpl.java new file mode 100644 index 0000000000..e3444cb125 --- /dev/null +++ b/group22/17457741/src/thirdwork/impl/ConnectionImpl.java @@ -0,0 +1,5 @@ +package thirdwork.impl; + +public class ConnectionImpl { + +} diff --git a/group22/17457741/src/thirdwork/impl/ConnectionManagerImpl.java b/group22/17457741/src/thirdwork/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..67d6e674dc --- /dev/null +++ b/group22/17457741/src/thirdwork/impl/ConnectionManagerImpl.java @@ -0,0 +1,5 @@ +package thirdwork.impl; + +public class ConnectionManagerImpl { + +} diff --git a/group22/2622819383/Task1/LinkedList.java b/group22/2622819383/Task1/LinkedList.java index 81c1db409c..57dfdef603 100644 --- a/group22/2622819383/Task1/LinkedList.java +++ b/group22/2622819383/Task1/LinkedList.java @@ -129,8 +129,11 @@ public Node insertAsSucc(Object data) { * Ѹ * Ϊ 3->7->10 , úΪ 10->7->3 */ - public void reverse(){ - + public void reverse(){ + int times = theSize; + int index = 0; + while (0 < --times) + add(index++, removeLast()); } /** @@ -139,8 +142,10 @@ public void reverse(){ * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 */ - public void removeFirstHalf(){ - + public void removeFirstHalf(){ + int times = theSize / 2; + while (0 < times--) + removeFirst(); } /** @@ -148,19 +153,46 @@ public void removeFirstHalf(){ * @param i * @param length */ - public void remove(int i, int length){ + public void remove(int i, int length){ + Node head = get(i).pred(); //ɾ(head, tail)֮Ԫ ɾ[i, i + length - 1]֮Ԫ + Node tail = get(i + length - 1).succ(); + head.succ = tail; + tail.pred = head; + theSize -= length; } /** * ٶǰlistе * ӵǰȡЩlistָԪ * 統ǰ = 11->101->201->301->401->501->601->701 - * listB = 1->3->4->6 + * list = 1->3->4->6 * صĽӦ[101,301,401,601] * @param list */ - public static int[] getElements(LinkedList list){ - return null; + public int[] getElements(LinkedList list){ + Iterator itSelf = iterator(); + Iterator itList = list.iterator(); + int[] ret = new int[list.size()]; + + int i = 0; //listԪصֵǰбҪȡԪص + lastI = 0;//һȡԪص + moveTimes = 0; + value = itSelf.next(); + index = 0;//ҪصԪص + + while (itList.hasNext()) { + i = itList.next(); + if (theSize <= i) throw new IndexOutOfBoundsException(); + + moveTimes = i - lastI; + while (0 < moveTimes--) + value = itSelf.next(); + + ret[index++] = value; + lastI = i; + } + + return ret; } /** @@ -169,9 +201,37 @@ public static int[] getElements(LinkedList list){ * @param list */ + //eȵԪصȣʧ򷵻-1 + private int find(Object e) { + Iterator it = iterator(); + int i = -1; //ҪصԪص + Object value = null; + + while (it.hasNext()) { + value = it.next(); + i++; + if (value == e) return i; + if (e < value) return -1; + } - public void subtract(LinkedList list){ - + return -1; + } + + public void subtract(LinkedList list){ + Iterator it = list.iterator(); + Object value = null; + int i = -1; + + while (it.hasNext()) { + value = it.next(); + i = find(value); + + //ɾȥظԪ + while (0 <= i) { + remove(i); + i = find(value); + } + } } /** @@ -179,7 +239,20 @@ public void subtract(LinkedList list){ * ɾֵͬĶԪأʹòԱԪصֵͬ */ public void removeDuplicateValues(){ - + Node current = header.succ(); + Node next = current; + int removedNum = 0; + + while ((next = next.succ()) != trailer) { + if (current.data() == next.data()) { + removedNum++; + } else { + current.succ = next; + next.pred = current; + current = next; + } + } + theSize -= removedNum; } /** @@ -188,7 +261,26 @@ public void removeDuplicateValues(){ * @param min * @param max */ + //[low, min]U[max, end] + + public void removeRange(int min, int max){ + //ɾȥ(i, j] + int i = 0, j = 0; + Iterator it = iterator(); + while (it.hasNext()) { + Object value = it.next(); + if (value <= min) i++; + if (value < max) j++; + else break; //if(max <= value) break; + } + + Node head = get(i); + Node tail = get(j).succ(); + + head.succ = tail; + tail.pred = head; + theSize -= (j - i); } @@ -197,7 +289,27 @@ public void removeRange(int min, int max){ * ҪCԪΪǰlistԪصĽұCеԪֵ * @param list */ - public LinkedList intersection( LinkedList list){ - return null; + //ABԪصĺϼ + public LinkedList intersection(LinkedList list){ + LinkedList ret = new LinkedList(); + Iterator it = iterator(); + Iterator itList = list.iterator(); + Object value1 = null, value2 = null; + + if (it.hasNext() && itList.hasNext()) { + value1 = it.next(); + value2 = itList.next(); + } + + while (value1 != null && value2 != null) { + if (value1 < value2) value1 = it.hasNext() ? it.next() : null; + else if (value2 < value1) value2 = itList.hasNext() ? itList.next() : null; + else { + ret.add(value1); + value1 = it.hasNext() ? it.next() : null; + value2 = itList.hasNext() ? itList.next() : null; + } + } + return ret; } } diff --git a/group22/2622819383/Task2/ArrayUtil.java b/group22/2622819383/Task2/ArrayUtil.java new file mode 100644 index 0000000000..ff947431ce --- /dev/null +++ b/group22/2622819383/Task2/ArrayUtil.java @@ -0,0 +1,272 @@ +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 lo = 0; + int hi = origin.length - 1; + while (lo < hi) + swap(origin, lo++, hi--); + } + private void swap(int[] array, int lo, int hi) { + int temp = array[lo]; + array[lo] = array[hi]; + array[hi] = 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 int[] removeZero(int[] oldArray){ + int[] ret = new int[oldArray.length]; + int i = 0; + for (int j = 0; j < oldArray.length; j++) { + if (oldArray[j] != 0) + ret[i++] = oldArray[j]; + } + int[] old = ret; + ret = new int[i]; + for (int j = 0; j < i; j++) + ret[j] = old[j]; + + return ret; + } + + /** + * Ѿõ飬 a1a2 , һµa3, ʹa3 a1a2 Ԫأ Ȼ + * 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){ + int m = array1.length; //array1 m i + int n = array2.length; //array2 n j + int[] ret = new int[m + n]; // ret m+n k + int k = 0; + for (int i = 0, j = 0; i < m || j < n; ) { + if (i < m && (n <= j || array1[i] < array2[j])) ret[k++] = array1[i++]; + if (j < n && (m <= i || array2[j] < array1[i])) ret[k++] = array2[j++]; + if (i < m && j < n && array1[i] == array2[j]) { + ret[k++] = array1[i++]; + j++; + } + } + int[] old = ret; + ret = new int[k]; + for (int i = 0; i < k; i++) + ret[i] = old[i]; + + return ret; + } + /** + * һѾݵ 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){ + int[] ret = new int[oldArray.length + size]; + + for (int i = 0; i < oldArray.length; i++) + ret[i] = oldArray[i]; + + return ret; + } + + /** + * 쳲Ϊ1123581321...... һֵ Сڸֵ + * 磬 max = 15 , 򷵻صӦΪ [11235813] + * max = 1, 򷵻ؿ [] + * @param max + * @return + */ + public int[] fibonacci(int max){ + int[] ret = new int[max / 2 + 10]; + int f = 1, g = 0, i = 0; + for ( ; f < max; i++) { + ret[i] = f; + f = g + f; + g = f - g; + } + int[] old = ret; + ret = new int[i]; + for (int j = 0; j < i; j++) + ret[j] = old[j]; + return ret; + } + + /** + * Сڸֵmax + * max = 23, صΪ[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + int[] ret = new int[max / 3 + 10]; //ʡʼٵĿռ䣻ret i + int i = 0; //iret + //˻: max < 5 + if (2 < max) { ret[i++] = 2; } + if (3 < max) { ret[i++] = 3; } + if (5 < max) { ret[i++] = 5; } + if (7 < max) { + //ֻΪ6k+16k+5 + //kСֵ1 + //жkֵ6k + 1 <= max6k + 5maxıȽҪԼȷ + int k = 1; + while (6 * k + 1 <= max) { + int m = 6 * k + 1; + int n = 6 * k + 5; + if(isPrime(ret, m)) ret[i++] = m; + if (max < n) break; + if (isPrime(ret, n)) ret[i++] = n; + k++; + } + }//O(n/3) * O((n^0.5) / 3) + int[] old = ret; + ret = new int[i]; + for (int j = 0; j < i; j++) + ret[j] = old[j]; + return ret; + } + + private boolean isPrime(int[] primeArray, int target) { + //O((n^0.5) / 3) + boolean isPrime = true; + int min = (int)Math.sqrt(target); + for (int i = 0; primeArray[i] <= min; i++) { + if (target % primeArray[i] == 0) { + isPrime = false; + break; + } + } + + return isPrime; + } + + /** + * ν ָǡõ֮ͣ6=1+2+3 + * һֵmax һ飬 Сmax + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + int[] ret = new int[48]; + int[] supportArr = getPrimes(max); + int j = 0; + for (int i = 2; i < max; i++) { + if (i % 2 != 0) continue; + if (isPerfectNumber(i, supportArr)) ret[j++] = i; + } + int[] old = ret; + ret = new int[j]; + for (int i = 0; i < j; i++) + ret[i] = old[i]; + return ret; + } + private boolean isPerfectNumber(int target, int[] supportArr) { + //ùʽperfectNum = ( 2^p-1 ) * 2^(p-1) = ( 2^(count+1)-1 ) * ( 2^count ) + //p=count+12^p-1=2^(count+1)-1Ҳ + //count: 2ĸ + boolean isPerfectNum = true; + int count = amountOfTwo(target); + + int test0 = (int)Math.pow(2, count); + int test1 = count + 1; + int test2 = test0 * 2 - 1; + + if (count == 0) isPerfectNum = false; + else if (!isPrime(supportArr, test1)) isPerfectNum = false; + else if (!isPrime(supportArr, test2)) isPerfectNum = false; + else if (test0 * test2 != target) isPerfectNum = false; + + return isPerfectNum; + } + private int amountOfTwo(int num) { + int count = 0; + while (num % 2 == 0) { + num /= 2; + count++; + } + return count; + } + + + /** + * seperator array + * array= [3,8,9], seperator = "-" + * 򷵻ֵΪ"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + String ret = ""; + if (array.length < 1) return ret; + ret += array[0]; + for (int i = 1; i < array.length; i++) + ret += seperator + array[i]; + return ret; + } + + public static void main(String[] args) { + ArrayUtil au = new ArrayUtil(); + + int[] arr0 = au.fibonacci(50000000); + for (int i = 0; i < arr0.length; i++) + System.out.print(arr0[i] + " "); + // arr1 = {3,}; + //System.out.println(au.join(arr0, "-")); + //System.out.println(au.join(arr1, "-")); + + } + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/group22/2622819383/Task2/litestruts/LoginAction.java b/group22/2622819383/Task2/litestruts/LoginAction.java new file mode 100644 index 0000000000..c3318361ae --- /dev/null +++ b/group22/2622819383/Task2/litestruts/LoginAction.java @@ -0,0 +1,41 @@ + + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public void setName(String name){ + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password){ + this.password = password; + } + + public String getMessage(){ + return this.message; + } + + 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"; + } +} diff --git a/group22/2622819383/Task2/litestruts/Struts.java b/group22/2622819383/Task2/litestruts/Struts.java new file mode 100644 index 0000000000..3109d1f40b --- /dev/null +++ b/group22/2622819383/Task2/litestruts/Struts.java @@ -0,0 +1,167 @@ +//ƪοѧԱ2415980327 + + +import java.io.InputStream; + +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 java.util.Set; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + + + +public class Struts { + + public static Element parseXml(String fileName) { + InputStream input = Struts.class.getResourceAsStream(fileName); + SAXReader reader = new SAXReader(); + Document document = null; + + try { + document = reader.read(input); + Element struts = document.getRootElement(); + return struts; + } catch (DocumentException e) { + e.printStackTrace(); + } + return null; + } + + public static View runAction(String actionName, Map parameters) { + + /* + + 0. ȡļstruts.xml + + 1. actionNameҵӦclass LoginAction, ͨʵ + parametersеݣösetter parametersе + ("name"="test" , "password"="1234") , + ǾӦõ setNamesetPassword + + 2. ͨöexectue ÷ֵ"success" + + 3. ͨҵgetter getMessage, + ͨã ֵγһHashMap , {"message": "¼ɹ"} , + ŵViewparameters + + 4. struts.xmlе ,Լexecuteķֵ ȷһjsp + ŵViewjspֶС + + */ + Element struts = parseXml("struts.xml"); + List actions = struts.elements(); + List resultRefs = new ArrayList<>(); + String actionClass = ""; + for (Element element : actions) + if (actionName.equals(element.attributeValue("name"))) { + actionClass = element.attributeValue("class"); + resultRefs = element.elements(); + break; + } + + Set attributes = parameters.keySet(); + Iterator it = attributes.iterator(); + try { + Object action = Class.forName(actionClass).newInstance(); + while (it.hasNext()) { + String attribute = it.next(); + Method method = action.getClass().getDeclaredMethod("set" + + attribute.substring(0, 1).toUpperCase() + + attribute.substring(1), String.class); + method.invoke(action, parameters.get(attribute)); + } + + Method execute = action.getClass().getDeclaredMethod("execute"); + String result = (String)execute.invoke(execute); + + Map actionParam = new HashMap(); + Method[] methods = action.getClass().getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().startsWith("get")) { + String methodName = method.getName(); + String name = methodName.substring(3, 4).toUpperCase() + methodName.substring(4); + String value = (String)method.invoke(action); + actionParam.put(name, value); + } + } + + + View view = new View(); + view.setParameters(actionParam); + for (Element element : resultRefs) { + if (result.equals(element.attributeValue("name"))) { + view.setJsp((String)element.getData()); + break; + } + } + return view; + + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) { + String actionName = "login"; + Element struts = parseXml("struts.xml"); + List actions = struts.elements(); + for (Element element : actions) { + if (actionName.equals(element.attributeValue("name"))) { + System.out.println(element.attributeValue("class")); + + for(Element element1:(List)element.elements()){ + System.out.println(element1.getData()); + } + } + } + } +} + + + + + + + + + + + + + + + + + + + + + diff --git a/group22/2622819383/Task2/litestruts/StrutsTest.java b/group22/2622819383/Task2/litestruts/StrutsTest.java new file mode 100644 index 0000000000..9b188e8d5a --- /dev/null +++ b/group22/2622819383/Task2/litestruts/StrutsTest.java @@ -0,0 +1,43 @@ + + +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"); //ԤIJһ + + 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/group22/2622819383/Task2/litestruts/View.java b/group22/2622819383/Task2/litestruts/View.java new file mode 100644 index 0000000000..4f2ca4ec30 --- /dev/null +++ b/group22/2622819383/Task2/litestruts/View.java @@ -0,0 +1,23 @@ + + +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/group22/2622819383/Task2/litestruts/struts.xml b/group22/2622819383/Task2/litestruts/struts.xml new file mode 100644 index 0000000000..e5842b0b17 --- /dev/null +++ b/group22/2622819383/Task2/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/group22/2622819383/Task3/LinkedList.java b/group22/2622819383/Task3/LinkedList.java new file mode 100644 index 0000000000..02ef7abc52 --- /dev/null +++ b/group22/2622819383/Task3/LinkedList.java @@ -0,0 +1,181 @@ +public class LinkedList { + /** + * Ѹ + * Ϊ 3->7->10 , úΪ 10->7->3 + */ + public void reverse() { + int times = theSize - 1; //һԪȻƶֻtheSize - 1β + int index = 0; + while (0 < times) { + add(index++, removeLast()); + times--; + } + } + + /** + * ɾһǰ벿 + * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + + */ + public void removeFirstHalf() { + int times = theSize / 2; + while (0 < times--) + removeFirst(); + } + + /** + * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * @param i + * @param length + */ + public void remove(int i, int length) { + Node head = get(i).pred(); //ɾ(head, tail)֮Ԫ ɾ[i, i + length - 1]֮Ԫ + Node tail = get(i + length - 1).succ(); + + head.succ = tail; + tail.pred = head; + theSize -= length; + } + /** + * ٶǰlistе + * ӵǰȡЩlistָԪ + * 統ǰ = 11->101->201->301->401->501->601->701 + * list = 1->3->4->6 + * صĽӦ[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list) { + Iterator it = iterator(); + int[] ret = new int[list.size()]; + int start = -1; + int value = 0; + int i = 0; //ret + + for (Integer num : list) { + while (start < num && it.hasNext()) { + value = it.next(); + start++; + } + ret[i++] = value; + } + return ret; + } + + /** + * ֪еԪֵУԵ洢ṹ + * ӵǰɾlistгֵԪ + + * @param list + */ + public void subtract(LinkedList list) { + Object current = null; + for (Object e : list) { + Iterator it = iterator(); + while (it.hasNext()) { + current = it.next(); + if (current.compareTo(e) == 0) + it.remove(); + if (current.compareTo(e) > 0) + break; + } + } + } + + /** + * ֪ǰеԪֵУԵ洢ṹ + * ɾֵͬĶԪأʹòԱԪصֵͬ + */ + public void removeDuplicateValues() { + Node current = header.succ(); + Node next = current; + int removedNum = 0; + + while ((next = next.succ()) != trailer) { + if (current.data() == next.data()) { + removedNum++; + } else { + current.succ = next; + next.pred = current; + current = next; + } + } + theSize -= removedNum; + } + + /** + * ֪еԪֵУԵ洢ṹ + * дһЧ㷨ɾֵminСmaxԪأдԪأ + * @param min + * @param max + */ + + + public void removeRange(int min, int max) { + //˫ɾȥ(p, q)Ľڵ + Node p = header; + Node q = null; + int removedNum = 0; //ҪɾȥڵĿ + while ((p = p.succ()) != trailer && (p.data() <= min)) + + p = p.prev(); + q = p; + while ((q = q.succ()) != trailer && (q.data() < max)) + removedNum++; + p.succ = q; + q.prev = p; + theSize -= removedNum; + + + + /* + //ɾȥ(i, j] + int i = 0, j = 0; + Iterator it = iterator(); + while (it.hasNext()) { + int value = it.next(); + if (value <= min) i++; + if (value < max) j++; + else break; //if(max <= value) break; + } + + Node head = get(i); + Node tail = get(j).succ(); + + head.succ = tail; + tail.pred = head; + theSize -= (j - i); + */ + + } + + /** + * 赱ǰͲlistָԪֵУͬһеԪֵͬ + * ҪCԪΪǰlistԪصĽұCеԪֵ + * @param list + */ + //ABԪصĺϼ + public LinkedList intersection(LinkedList list) { + LinkedList ret = new LinkedList(); + Iterator it = iterator(); + Iterator itList = list.iterator(); + Object value1 = null, value2 = null; + + if (it.hasNext() && itList.hasNext()) { + value1 = it.next(); + value2 = itList.next(); + } + //nullΪϵı־ + //ѭ־һLinkedListѾ + while (value1 != null && value2 != null) { + if (value1 < value2) value1 = it.hasNext() ? it.next() : null; + else if (value2 < value1) value2 = itList.hasNext() ? itList.next() : null; + else { + ret.add(value1); + value1 = it.hasNext() ? it.next() : null; + value2 = itList.hasNext() ? itList.next() : null; + } + } + return ret; + } +} diff --git a/group22/2622819383/Task3/download/Connection.java b/group22/2622819383/Task3/download/Connection.java new file mode 100644 index 0000000000..14eb68f232 --- /dev/null +++ b/group22/2622819383/Task3/download/Connection.java @@ -0,0 +1,53 @@ +import java.net.URL; +import java.net.HttpURLConnection; +import java.io.IOException; +import java.io.InputStream; +import java.io.ByteArrayOutputStream; + +public class Connection { + private URL url; + private HttpURLConnection conn; + + //һConnectionӦһHttpURLConnection + public Connection(String url) { + try { + this.url = new URL(url); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void initConnection() { + try { + conn = (HttpURLConnection)url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + //ӷstartPos-endPosֽڷΧԴݵһֽ + //Range: ڿͻ˵˵󣬿ֶָͨļijһδС䵥λ + public byte[] read(int startPos, int endPos) throws IOException { + initConnection(); + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream in = conn.getInputStream(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + byte[] buf = new byte[1024]; + int hasRead = 0; + while ((hasRead = in.read(buf)) != -1) { + out.write(buf, 0, hasRead); + } + out.close(); + in.close(); + return out.toByteArray(); + } + + public int getContentLength() { + initConnection(); + return conn.getContentLength(); + } + + public void close() { + } +} \ No newline at end of file diff --git a/group22/2622819383/Task3/download/DownloadThread.java b/group22/2622819383/Task3/download/DownloadThread.java new file mode 100644 index 0000000000..a04911cf7c --- /dev/null +++ b/group22/2622819383/Task3/download/DownloadThread.java @@ -0,0 +1,34 @@ +import java.io.IOException; +import java.net.HttpURLConnection; +import java.io.RandomAccessFile; +import java.util.concurrent.locks.*; +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String targetURL; + //final ReentrantLock lock = new ReentrantLock(); + + + public DownloadThread(Connection conn, int startPos, int endPos, String targetURL) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.targetURL = targetURL; + } + + public void run() { + System.out.println("߳" + getName() + "startPos:" + startPos + "; endPos:" + endPos); + try { + RandomAccessFile raf = new RandomAccessFile(targetURL, "rw"); + byte[] buf = conn.read(startPos, endPos); + raf.seek(startPos); + raf.write(buf); + raf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("߳" + this.getName() + "."); + } +} diff --git a/group22/2622819383/Task3/download/FileDownloader.java b/group22/2622819383/Task3/download/FileDownloader.java new file mode 100644 index 0000000000..c4d8fa167d --- /dev/null +++ b/group22/2622819383/Task3/download/FileDownloader.java @@ -0,0 +1,66 @@ +import java.util.List; +import java.util.ArrayList; +import java.io.RandomAccessFile; +import java.io.IOException; +public class FileDownloader { + + String url; + + public FileDownloader(String url) { + this.url = url; + } + + public void execute() throws IOException { + // ʵĴ룬 ע⣺ Ҫö߳ʵ + // ӿ, Ҫд⼸ӿڵʵִ + // (1) ConnectionManager , ԴһӣͨConnectionԶȡеһΣstartPos, endPosָ + // (2) DownloadListener, Ƕ߳أ Ŀͻ˲֪ʲôʱҪʵֵ + // ̶ִ߳Ժ listenernotifiedFinished ͻ˾յ֪ͨ + // ʵ˼· + // 1. ҪConnectionManageropenӣ ȻͨConnection.getContentLengthļij + // 2. 3߳أ עÿ߳ҪȵConnectionManageropen + // Ȼread readжȡļĿʼλúͽλõIJ ֵbyte[] + // 3. byteд뵽ļ + // 4. е̶߳Ժ ҪlistenernotifiedFinished + + // Ĵʾ룬 Ҳ˵ֻһ̣߳ Ҫɶ̵߳ġ + Connection conn = null; + conn = new Connection(url); + int length = conn.getContentLength(); + String targetURL = "E:/" + url.substring(url.lastIndexOf("/") + 1); + RandomAccessFile raf = new RandomAccessFile(targetURL, "rw"); + raf.setLength(length); + raf.close(); + + for (int i = 0; i < 3; i++) { + int part = length / 3; + int start = i * part; + int end = (i == 2) ? length - 1 : (i + 1) * part - 1; + DownloadThread t = new DownloadThread(conn, start, end, targetURL); + t.start(); + } + } + + /* + DownloadListener listener; + 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) { + try { + new FileDownloader("http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png").execute(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group22/627559964/src/com/coderising/download/DownloadThread.java b/group22/627559964/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..5497305ea7 --- /dev/null +++ b/group22/627559964/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,45 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + + +public class DownloadThread extends Thread { + + Connection conn; + int startPos; + int endPos; + CyclicBarrier barrier; + String localFile; + + public DownloadThread(Connection conn, int startPos, int endPos, CyclicBarrier barrier, String localFile) { + super(); + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.barrier = barrier; + this.localFile = localFile; + } + + public void run() { + + try { + + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile,"rw"); + file.seek(startPos); + file.write(data); + file.close(); + conn.close(); + barrier.await(); //等待别的线程完成 + + } catch (Exception e) { + e.printStackTrace(); + + } + } +} diff --git a/group22/627559964/src/com/coderising/download/FileDownloader.java b/group22/627559964/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..fa4375df7b --- /dev/null +++ b/group22/627559964/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,122 @@ +package com.coderising.download; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +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 { + + private String url; + private DownloadListener listener; + private ConnectionManager cm; + private String localFile; + int threadNum = 3; + + public FileDownloader(String url, String localFile) { + super(); + 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(threadNum, new Runnable(){ + + @Override + public void run() { + listener.notifyFinished(); + } + + }); + + Connection conn = null; + try { + + conn = cm.open(this.url); + int length = conn.getContentLength(); + int threadPart = length / threadNum + 1; + createPlaceHolderFile(this.localFile, length); + int[][] ranges = allocateDownloadRange(threadNum, length); + for (int i = 0; i < this.threadNum; i++) { + + DownloadThread thread = new DownloadThread(cm.open(url), ranges[i][0], ranges[i][1], barrier, localFile); + thread.start(); + + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException{ + + RandomAccessFile file = new RandomAccessFile(fileName,"rw"); + + for(int i=0; i length) { + byte[] file = out.toByteArray(); + return Arrays.copyOf(file, length); + } + + return out.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() { + + } + +} diff --git a/group22/627559964/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group22/627559964/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..9719f8ff51 --- /dev/null +++ b/group22/627559964/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,20 @@ +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 { + + return new ConnectionImpl(url); + } + +} diff --git a/group22/627559964/src/com/coding/basic/LinkedList.java b/group22/627559964/src/com/coding/basic/LinkedList.java index dcae1fb835..39b0250ae3 100644 --- a/group22/627559964/src/com/coding/basic/LinkedList.java +++ b/group22/627559964/src/com/coding/basic/LinkedList.java @@ -1,7 +1,7 @@ package com.coding.basic; /** - * ԶLinkList + * 自定义LinkList * * @author xiongrui233 * @@ -9,7 +9,7 @@ public class LinkedList implements List { /** - * ڵṹ + * 定义链表节点结构 * * @author xiongrui233 * @@ -19,7 +19,7 @@ private static class Node { Node next; } - // ڵ + // 链表节点 private Node head = new Node(); private int size = 0; @@ -29,7 +29,7 @@ public LinkedList() { } /** - * Ԫ + * 添加元素 * * @param o */ @@ -38,7 +38,7 @@ public void add(Object o) { } /** - * Ԫ + * 添加元素 * * @param index * @param o @@ -64,7 +64,7 @@ public void add(int index, Object o) { } /** - * ȡԪ + * 获取元素 * * @param index */ @@ -77,7 +77,7 @@ public Object get(int index) { } /** - * ɾԪ + * 删除元素 * * @param index */ @@ -102,7 +102,7 @@ public Object remove(int index) { } /** - * LinkedListĴС + * 返回LinkedList的大小 * * @return size */ @@ -111,7 +111,7 @@ public int size() { } /** - * LinkedListһλԪ + * 在LinkedList第一的位置添加元素 * * @param o */ @@ -120,7 +120,7 @@ public void addFirst(Object o) { } /** - * LinkedListԪ + * 在LinkedList最后添加元素 * @param o */ public void addLast(Object o) { @@ -135,7 +135,7 @@ public void addLast(Object o) { } /** - * ƳһλԪ + * 移除链表第一位元素 * * @return obj */ @@ -144,7 +144,7 @@ public Object removeFirst() { } /** - * ƳһλԪ + * 移除链表最后一位元素 * * @return obj */ @@ -153,7 +153,7 @@ public Object removeLast() { } /** - * ʵIteratorӿ + * 实现Iterator接口 * * @return Iterator */ @@ -185,7 +185,7 @@ public Object next() { } /** - * Ѹ Ϊ 3->7->10 , úΪ 10->7->3 + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public LinkedList reverse() { LinkedList lis = new LinkedList(); @@ -196,8 +196,8 @@ public LinkedList reverse() { } /** - * ɾһǰ벿 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 list = 2->5->7->8->10 - * ,ɾԺֵΪ7,8,10 + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 */ public void removeFirstHalf() { int mid = size/2; @@ -207,7 +207,7 @@ public void removeFirstHalf() { } /** - * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * * @param i * @param length @@ -225,9 +225,9 @@ public void remove(int i, int length) { } /** - * ٶǰlistе ӵǰȡЩlistָԪ 統ǰ = + * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = * 11->101->201->301->401->501->601->701 listB = 1->3->4->6 - * صĽӦ[101,301,401,601] + * 返回的结果应该是[101,301,401,601] * * @param list */ @@ -243,7 +243,7 @@ public int[] getElements(LinkedList list) { } /** - * ֪еԪֵУԵ洢ṹ ӵǰɾlistгֵԪ + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 * * @param list */ @@ -261,7 +261,7 @@ public void subtract(LinkedList list) { } /** - * ֪ǰеԪֵУԵ洢ṹ ɾֵͬĶԪأʹòԱԪصֵͬ + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues() { for (int i = 0; i < this.size; i++) { @@ -276,7 +276,7 @@ public void removeDuplicateValues() { } /** - * ֪еԪֵУԵ洢ṹ дһЧ㷨ɾֵminСmaxԪأдԪأ + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * * @param min * @param max @@ -293,8 +293,8 @@ public void removeRange(int min, int max) { } /** - * 赱ǰͲlistָԪֵУͬһеԪֵͬ - * ҪCԪΪǰlistԪصĽұCеԪֵ + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * TODO * @param list */ diff --git a/group22/627559964/src/demo/SimpleDownLoad.java b/group22/627559964/src/demo/SimpleDownLoad.java new file mode 100644 index 0000000000..1931fd5d38 --- /dev/null +++ b/group22/627559964/src/demo/SimpleDownLoad.java @@ -0,0 +1,54 @@ +package demo; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +public class SimpleDownLoad { + + public static void main(String[] args) { + String downUrl = "https://ss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/super/crop=378,138,1512,942/sign=9cca06797b3e6709aa4f1fbf06f4a805/f9198618367adab471a1e11d8fd4b31c8701e47f.jpg"; + String dirUrl = "C:\\Users\\Administrator\\Desktop\\1.jpg"; + + InputStream in = null; + OutputStream out = null; + + try { + URL url = new URL(downUrl); + URLConnection connection = url.openConnection(); + in = connection.getInputStream(); + + File file = new File(dirUrl); + out = new FileOutputStream(file); + + byte[] files = new byte[1024]; + int length = 0; + while ((length = in.read(files)) > -1) { + out.write(files, 0, length); + } + + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + try { + in.close(); + out.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + + } + +} diff --git "a/group22/910725683/CPU\357\274\214\345\206\205\345\255\230\357\274\214\347\241\254\347\233\230\357\274\214\346\214\207\344\273\244\344\273\245\345\217\212\345\256\203\344\273\254\344\271\213\351\227\264\347\232\204\345\205\263\347\263\273.md" "b/group22/910725683/week01/CPU\357\274\214\345\206\205\345\255\230\357\274\214\347\241\254\347\233\230\357\274\214\346\214\207\344\273\244\344\273\245\345\217\212\345\256\203\344\273\254\344\271\213\351\227\264\347\232\204\345\205\263\347\263\273.md" similarity index 100% rename from "group22/910725683/CPU\357\274\214\345\206\205\345\255\230\357\274\214\347\241\254\347\233\230\357\274\214\346\214\207\344\273\244\344\273\245\345\217\212\345\256\203\344\273\254\344\271\213\351\227\264\347\232\204\345\205\263\347\263\273.md" rename to "group22/910725683/week01/CPU\357\274\214\345\206\205\345\255\230\357\274\214\347\241\254\347\233\230\357\274\214\346\214\207\344\273\244\344\273\245\345\217\212\345\256\203\344\273\254\344\271\213\351\227\264\347\232\204\345\205\263\347\263\273.md" diff --git a/group22/910725683/week01/src/com/coding/basic/ArrayList.java b/group22/910725683/week01/src/com/coding/basic/ArrayList.java index acc0e9f8f4..becbf4f907 100644 --- a/group22/910725683/week01/src/com/coding/basic/ArrayList.java +++ b/group22/910725683/week01/src/com/coding/basic/ArrayList.java @@ -3,10 +3,10 @@ public class ArrayList implements List { - //ʼ// + //数组初始容量// private final int DEFAULT_CAPICITY=7; - //Ԫظ// + //数组元素个数// private int size = 0; private Object[] elementData = new Object[DEFAULT_CAPICITY]; @@ -16,11 +16,11 @@ public void add(Object o){ elementData[size++]=o; } public void add(int index, Object o){ - //indexҪ// + //index要连续的增加// checkIndex(index); ensureCapcity(size+1); - /* indexԪһλ,indexʼƶעindex0ʼ - * Ҫ+1򳤶Ϊsize-((index)+1)+1 + /* index及后面的元素左移一位,即从index开始移动,注意index从0开始, + * 即还要+1,则长度为size-((index)+1)+1 */ System.arraycopy(elementData, index, elementData, index+1, size-index); elementData[index]=o; @@ -35,8 +35,8 @@ public Object get(int index){ public Object remove(int index){ checkIndex(index); Object temp=elementData[index]; - /* indexԪһλ,index+1ʼƶעindex0ʼ - * Ҫ+1򳤶Ϊsize-((index+1)+1)+1 + /* index后面的元素左移一位,即从index+1开始移动,注意index从0开始, + * 即还要+1,则长度为size-((index+1)+1)+1 */ System.arraycopy(elementData, index+1, elementData, index, size-index-1); size--; @@ -62,30 +62,30 @@ public Object next(){ } } - //ж±ǷԽ粢ʾ// + //判断请求的下标是否越界并提示// private void checkIndex(int index){ if (index<0 || index >=size){ throw new IndexOutOfBoundsException("get " + index+" in "+size); } } - //жǷҪݲ// + //判断是否需要扩容并完成扩容// private void ensureCapcity(int size){ int oldLength=elementData.length; if (size>=oldLength){ - //util.ArrayListеĹʽԴʹõ12// + //util.ArrayList中的公式,源代码使用的右移1,即除2// int newLength=oldLength/2+oldLength; if (newLength7->10 , úΪ 10->7->3 + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ - /*ָ룬ʼʱָͷͷһ(ǰָ롢ָ) - *ѭÿƶ1ָƵβsize-1ڵҪƶ(size-1)-1 - *ȱǰֵָtempǰͷȻƶǰָ - *ƶ󣬽ǰָĽڵӵͷʼһƶ - *ѭע⵽ʵֻоĵڶڵ㵽ڸڵ㣬Ҫͷβڵ - *βڵҪӵͷͷڵָÿգȻ1<->2 - *άͷβ + /*两个指针,开始的时候指向头跟头后面的一个(前指针、后指针) + *循环:每次向后移动步长1,至后指针移到链表尾,size-1个节点需要移动(size-1)-1次 + *先保留前指针的值temp,即当前逆序链表的头,然后再移动前、后指针 + *移动后,将前指针的节点连接到逆序链表的头,开始下一次移动 + *循环结束后,注意到实际重连的只有旧链表的第二个节点到倒数第个节点,需要单独处理旧链表的头尾节点 + *旧链表的尾节点需要链接到逆序链表的头,旧链表的头节点的指针置空,不然会1<->2 + *维护头尾标记 */ Node current=head; Node currentAfter=current.next; @@ -161,12 +161,12 @@ public void reverse(){ } /** - * ɾһǰ벿 - * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 - * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf(){ - //intضϣС// + //int截断,不会有小数// int removeLength = size / 2; for (int i=1;i<=removeLength;i++){ removeFirst(); @@ -174,7 +174,7 @@ public void removeFirstHalf(){ } /** - * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * @param i * @param length */ @@ -184,17 +184,17 @@ public void remove(int i, int length){ if (i+length-1>size){ length=size-i; } - //ӺǰɾֹԽ// + //从后往前删除,防止越界// for (int k=length;k>=i;k--){ remove(k); } } /** - * ٶǰlistе - * ӵǰȡЩlistָԪ - * 統ǰ = 11->101->201->301->401->501->601->701 + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 * listB = 1->3->4->6 - * صĽӦ[101,301,401,601] + * 返回的结果应该是[101,301,401,601] * @param list */ public int[] getElements(LinkedList list){ @@ -212,11 +212,11 @@ public int[] getElements(LinkedList list){ } /** - * ֪еԪֵУԵ洢ṹ - * ӵǰɾlistгֵԪ + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 * @param list */ - //ע⵽ѭlistʱ򣬱ڲѭıȽĽڵ±겢// + //注意到递增,在外层循环list的时候,保留内层循环的被比较链表的节点的下标并递增即可// public void subtract(LinkedList list){ int startIndex=0; Iterator iter=list.iterator(); @@ -235,10 +235,10 @@ public void subtract(LinkedList list){ } /** - * ֪ǰеԪֵУԵ洢ṹ - * ɾֵͬĶԪأʹòԱԪصֵͬ + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ - //ע⵽ҪɾĽڵ±겢// + //注意到递增,保留不需要删除的节点的下标并递增即可// public void removeDuplicateValues(){ int startIndex=1; int scr=(int)head.data; @@ -253,12 +253,12 @@ public void removeDuplicateValues(){ } /** - * ֪еԪֵУԵ洢ṹ - * дһЧ㷨ɾֵminСmaxԪأдԪأ + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * @param min * @param max */ - //öַǵû뵽Ч㷨˵BȻᡣһһȽϵ// + //这个,想用二分法但是是单链表,没想到高效的算法(网上说是B树,然而不会。。。),一个一个比较的// public void removeRange(int min, int max){ Node current=head; Node temp=head; @@ -283,11 +283,11 @@ public void removeRange(int min, int max){ } /** - * 赱ǰͲlistָԪֵУͬһеԪֵͬ - * ҪCԪΪǰlistԪصĽұCеԪֵ + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ - //ע⵽ѭ±λõ// + //注意到递增,保留内循环下标位置递增即可// public LinkedList intersection( LinkedList list){ LinkedList result = new LinkedList(); int startIndex = 0; diff --git a/group16/1012075117/DataStructure219/.classpath b/group22/910725683/week02/array/.classpath similarity index 71% rename from group16/1012075117/DataStructure219/.classpath rename to group22/910725683/week02/array/.classpath index fceb4801b5..1b83178c00 100644 --- a/group16/1012075117/DataStructure219/.classpath +++ b/group22/910725683/week02/array/.classpath @@ -1,6 +1,8 @@ + + diff --git a/group22/910725683/week02/array/.gitignore b/group22/910725683/week02/array/.gitignore new file mode 100644 index 0000000000..6a59c3a991 --- /dev/null +++ b/group22/910725683/week02/array/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/.settings/ +.classpatch +.prject \ No newline at end of file diff --git a/group22/910725683/week02/array/.project b/group22/910725683/week02/array/.project new file mode 100644 index 0000000000..c6387dd971 --- /dev/null +++ b/group22/910725683/week02/array/.project @@ -0,0 +1,17 @@ + + + week02-array + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group22/910725683/week02/array/src/com/coderising/array/ArrayUtil.java b/group22/910725683/week02/array/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..347a230118 --- /dev/null +++ b/group22/910725683/week02/array/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,235 @@ +package com.coderising.array; + +import java.util.ArrayList; +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 void reverseArray(int[] origin){ + int arrayLength = origin.length; + //注意整数截断,奇数长度不用额外处理 + for (int i = 0 ; i < arrayLength / 2 ; i++){ + int temp = origin[i]; + origin[i]=origin[arrayLength - i - 1]; + origin[arrayLength - i - 1] = 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 int[] removeZero(int[] oldArray){ + int newArrayLength = 0; + for (int i : oldArray){ + if (i != 0){ + newArrayLength ++; + } + } + + int[] newArray = new int[newArrayLength]; + int newArrayIndex = 0; + for (int i : oldArray){ + if (i != 0){ + newArray[newArrayIndex++] = i; + } + } + + return newArray; + } + + /** + * 给定两个已经排序好的整形数组, 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){ + + //注意此处算出来的newArrayLength是最大值,实际可能小于这个长度 + int newArrayLength = array1.length + array2.length; + int[] newArray = new int[newArrayLength]; + final int MAX_VALUE = Integer.MAX_VALUE; + int index1 = 0; + int index2 = 0; + int newArrayIndex = 0; + int element1; + int element2; + + //注意是两个数组都是递增的,可以交替步进比较,当大小翻转的时候交替,要求踢重,则相等的时候步进但不保存 + while(index1 < array1.length || index2 < array2.length){ + + //此处取巧的点在于已知数组是int型,故最大值是已知的,当步进到头时取最大值,即“钳位” + if (index1 < array1.length){ + element1 = array1[index1]; + }else{ + element1 = MAX_VALUE; + } + + if (index2 < array2.length){ + element2 = array2[index2]; + }else{ + element2 = MAX_VALUE; + } + + //谁小谁步进 + if (element1 < element2){ + newArray[newArrayIndex++] = element1; + index1++; + }else{ + if (element1 == element2){ + //相等后不再赋值给新数组 + index2++; + }else{ + newArray[newArrayIndex++] = element2; + index2++; + } + } + } + //移除没用到的位置 + return Arrays.copyOf(newArray, newArrayIndex); + } + /** + * 把一个已经存满数据的数组 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){ + int[] newArray = new int[oldArray.length + size]; + //Java对引用类型自动赋值,故0不需要额外的处理 + System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); + 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 int[] fibonacci(int max){ + ArrayList list = new ArrayList(); + int index = 0; + if (max >= 2){ + while( true ){ + int fibonacciNum = getFibonacci(index++); + if ( fibonacciNum < max ){ + list.add(fibonacciNum); + }else{ + break; + } + } + } + return list2Array(list); + } + + private int getFibonacci(int index){ + if (index == 0){ return 1; } + if (index == 1){ return 1; } + return getFibonacci(index - 2) + getFibonacci(index - 1); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + ArrayList list = new ArrayList(); + + for (int i = 0 ; i < max ; i++){ + if (isPrime(i)){ list.add(i); } + } + + return list2Array(list); + } + + private boolean isPrime(int num){ + if (num == 0 || num == 1){ + return false; + } + for (int i = 2 ; i <= num / 2 ; i++){ + if (num % i == 0){ + return false; + } + } + return true; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + ArrayList list = new ArrayList(); + + for (int i = 1 ; i < max ; i++){ + if (isPerfectNumbers(i)){ list.add(i); } + } + + return list2Array(list); + } + + private boolean isPerfectNumbers(int num){ + if (num == 1){ + return false; + } + int sum = 1; + //注意因子是对称的,故比较的上限是的平方根 + int sqr = (int) Math.sqrt(num); + for (int i = 2 ; i <= sqr ; i++){ + if (num % i == 0){ + sum = sum + i + num / i; + } + } + return sum == num; + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + StringBuilder sb = new StringBuilder(); + for (int i = 0 ; i < array.length ; i++){ + sb.append(array[i]); + if (i != array.length - 1){ + sb.append(seperator); + } + } + return sb.toString(); + } + + private int[] list2Array(ArrayList list){ + int[] array = new int[list.size()]; + for (int i = 0 ; i < list.size() ; i++){ + array[i] = (int) list.get(i); + } + return array; + } +} \ No newline at end of file diff --git a/group22/910725683/week02/array/test/com/coderising/array/ArrayUtilTest.java b/group22/910725683/week02/array/test/com/coderising/array/ArrayUtilTest.java new file mode 100644 index 0000000000..483a537bd6 --- /dev/null +++ b/group22/910725683/week02/array/test/com/coderising/array/ArrayUtilTest.java @@ -0,0 +1,58 @@ +package com.coderising.array; + +import static org.junit.Assert.*; + +import org.junit.Assert; +import org.junit.Test; + +public class ArrayUtilTest { + + ArrayUtil au = new ArrayUtil(); + + @Test + public void testReverseArray() { + int[] a = new int[]{7, 9 , 30, 3}; + au.reverseArray(a); + Assert.assertArrayEquals(new int[]{3, 30, 9,7}, a); + int[] b = new int[]{7, 9, 30, 3, 4}; + au.reverseArray(b); + Assert.assertArrayEquals(new int[]{4,3, 30 , 9,7}, b); + } + + @Test + public void testRemoveZero() { + Assert.assertArrayEquals(new int[]{1,3,4,5,6,6,5,4,7,6,7,5}, au.removeZero(new int[]{1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5})); + } + + @Test + public void testMerge() { + Assert.assertArrayEquals(new int[]{3,4,5,6,7,8}, au.merge(new int[]{3, 5, 7,8}, new int[]{4, 5, 6,7})); + } + + @Test + public void testGrow() { + Assert.assertArrayEquals(new int[]{2,3,6,0,0,0},au.grow(new int[]{2,3,6},3)); + } + + @Test + public void testFibonacci() { + Assert.assertArrayEquals(new int[]{1,1,2,3,5,8,13}, au.fibonacci(15)); + Assert.assertArrayEquals(new int[]{}, au.fibonacci(1)); + } + + @Test + public void testGetPrimes() { + Assert.assertArrayEquals(new int[]{2,3,5,7,11,13,17,19}, au.getPrimes(23)); + } + + @Test + public void testGetPerfectNumbers() { + Assert.assertArrayEquals(new int[]{6,28}, au.getPerfectNumbers(100)); + } + + @Test + public void testJoin() { + Assert.assertEquals("3-8-9", au.join(new int[]{3,8,9}, "-")); + } + +} diff --git a/group22/910725683/week02/litestruts/.classpath b/group22/910725683/week02/litestruts/.classpath new file mode 100644 index 0000000000..23aba3c3c9 --- /dev/null +++ b/group22/910725683/week02/litestruts/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/group22/910725683/week02/litestruts/.gitignore b/group22/910725683/week02/litestruts/.gitignore new file mode 100644 index 0000000000..6a59c3a991 --- /dev/null +++ b/group22/910725683/week02/litestruts/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/.settings/ +.classpatch +.prject \ No newline at end of file diff --git a/group22/910725683/week02/litestruts/.project b/group22/910725683/week02/litestruts/.project new file mode 100644 index 0000000000..2e44abe22a --- /dev/null +++ b/group22/910725683/week02/litestruts/.project @@ -0,0 +1,17 @@ + + + week02-litestruts + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group22/910725683/week02/litestruts/src/com/coderising/litestruts/LoginAction.java b/group22/910725683/week02/litestruts/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..eef38d702e --- /dev/null +++ b/group22/910725683/week02/litestruts/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/group22/910725683/week02/litestruts/src/com/coderising/litestruts/Struts.java b/group22/910725683/week02/litestruts/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..36f5f3838f --- /dev/null +++ b/group22/910725683/week02/litestruts/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,95 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.dom4j.Document; +import org.dom4j.Node; +import org.dom4j.io.SAXReader; + +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字段中。 + */ + View view = new View(); + + try{ + //读取strut.xml + SAXReader saxReader = new SAXReader(); + Document document = saxReader.read("struts.xml"); + + try { + //XPath解析DOM树,获得actionName对应的类名称(XPath在爬虫里也非常好用) + Node actionClass = document.selectSingleNode("/struts/action[@name=\"" + actionName + "\"]/@class"); + Class classtype = Class.forName(actionClass.getText()); + Object obj = classtype.newInstance(); + + //按照parameters设置实例变量 + for (Entry entry : parameters.entrySet()){ + setter(obj,entry.getKey(),entry.getValue(),String.class); + } + try{ + //执行execute方法 + Method met = classtype.getMethod("execute"); + String result = (String) met.invoke(obj); + //获得执行后实例变量的值 + HashMap hashmap = new HashMap(); + for(Method m : classtype.getMethods() ) { + String methodName = m.getName(); + if (methodName.startsWith("get")){ + hashmap.put(methodName.substring(3,4).toLowerCase() + methodName.substring(4), m.invoke(obj).toString()); + } + } + view.setParameters(hashmap); + //获得执行结果对应的jsp + Node jsp = document.selectSingleNode("/struts/action[@name=\"" + actionName + "\"]/result[@name=\"" + result + "\"]"); + view.setJsp(jsp.getText()); + + } + catch(Exception e){ + e.printStackTrace(); + } + } + catch (Exception e){ + e.printStackTrace(); + } + }catch (Exception e) { + e.printStackTrace(); + } + return view; + } + + //按照参数名运行setter方法 + private static void setter(Object obj,String att,Object value,Class type){ + try{ + Method met = obj.getClass().getMethod("set"+initStr(att),type); + met.invoke(obj,value) ; + }catch(Exception e){ + e.printStackTrace() ; + } + } + + //小写驼峰命名法 + private static String initStr(String str){ + char[] ch = str.toCharArray(); + if (ch[0] >= 'a' && ch[0] <= 'z') { + ch[0] = (char) (ch[0] - 32); + } + return new String(ch); + } + +} diff --git a/group22/910725683/week02/litestruts/src/com/coderising/litestruts/View.java b/group22/910725683/week02/litestruts/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group22/910725683/week02/litestruts/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group22/910725683/week02/litestruts/struts.xml b/group22/910725683/week02/litestruts/struts.xml new file mode 100644 index 0000000000..171848ecd1 --- /dev/null +++ b/group22/910725683/week02/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/group22/910725683/week02/litestruts/test/com/coderising/litestruts/StrutsTest.java b/group22/910725683/week02/litestruts/test/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..7e45e699df --- /dev/null +++ b/group22/910725683/week02/litestruts/test/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,40 @@ +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/group24/1054283210/src/com/github/xiaozi123/coding2017/basic/LinkedList.java b/group24/1054283210/src/com/github/xiaozi123/coding2017/basic/LinkedList.java index 66ab1e0300..9b63437dd2 100644 --- a/group24/1054283210/src/com/github/xiaozi123/coding2017/basic/LinkedList.java +++ b/group24/1054283210/src/com/github/xiaozi123/coding2017/basic/LinkedList.java @@ -1,141 +1,307 @@ package com.github.xiaozi123.coding2017.basic; +import java.util.HashSet; import java.util.NoSuchElementException; - -import jdk.nashorn.internal.ir.IndexNode; +import java.util.Set; public class LinkedList implements List { - - private Node head; + private int size; - - private Node node(Object o) { - Node now=new Node(); - now.data=o; - now.next=null; - size++; - return now; + private Node head; + private Node last; + + public void add(Object o) { + addLast(o); } - - public void add(Object o){ - if (head==null) { - head=node(o); + + public void addLast(Object o) { + final Node l = last; + final Node newNode = new Node(o, null); + last = newNode; + if (l == null) + head = newNode; + else + l.next = newNode; + size ++; + } + + public void add(int index , Object o) { + makeSure(index); + if (index == 0){ + addFirst(o); + }else { + final Node preNode = getPreNode(index); + final Node nextNode = preNode.next; + final Node newNode = new Node(o, nextNode); + preNode.next = newNode; } - else { - addLast(o); + } + + public void addFirst(Object o){ + final Node h = head; + final Node newNode = new Node(o, head); + head = newNode; + if (h == null) + last = newNode; + size++; + } + + private Node getPreNode(int index) { + Node preNode = head; + for (int i = 0 ; i != index - 1 && preNode != null; ++i) { + preNode = preNode.next; } - + return preNode; } - public void add(int index , Object o){ - if (index<0||index>size) { - throw new IndexOutOfBoundsException("OutOfBound"); - }else if (index==0) { - addFirst(o); - }else if (index==size+1) { - addLast(o); - }else{ - Node beforeNode=head; - for (int i = 0; i < index-1; i++) { - beforeNode=beforeNode.next; + + private void makeSure(int index) { + if (index >= size || index < 0) + throw new IndexOutOfBoundsException(); + } + + public Object get(int index) { + Object targetData = null; + makeSure(index); + Iterator iterator = iterator(); + for (int i = 0; iterator.hasNext(); ++i, iterator.next()) { + if (i == index) { + targetData = iterator.next(); + break; } - Node addNode=node(o); - addNode.next=beforeNode.next; - beforeNode.next=addNode; - } + } + return targetData; } - - - public Object get(int index){ - if (index<0||index>size) { - throw new IndexOutOfBoundsException("OutOfBound"); + + public Object remove(int index) { + if (size <= 0) + throw new IndexOutOfBoundsException(); + makeSure(index); + Object oldData; + if (index == 0) { + oldData = removeFirst(); + } else if (index == size - 1) { + oldData = removeLast(); } else { - Node indexNode=head; - for (int i = 0; i < index; i++) { - indexNode=indexNode.next; - } - return indexNode.data; + final Node preNode = getPreNode(index); + final Node nextNode = preNode.next.next; + oldData = preNode.next.data; + preNode.next = nextNode; + size --; } - + return oldData; } - public Object remove(int index){ - if (index<0||index>size) { - throw new IndexOutOfBoundsException("OutOfBound"); - }else if(index==0){ - return removeFirst(); - }else if(index==size){ - return removeLast(); - - }else{ - Node beforeNode=head; - for (int i = 0; i < index-1; i++) { - beforeNode=beforeNode.next; - } - - Node indexNode=head; - for (int i = 0; i < index; i++) { - indexNode=indexNode.next; - } - beforeNode.next=indexNode.next; - indexNode.next=null; - size--; - return indexNode.data; - } + + public Object removeFirst() { + Object oldData; + final Node h = head.next; + oldData = head.data; + head = h; + size --; + return oldData; + } + + public Object removeLast() { + Object oldData; + final Node l = getPreNode(size); + oldData = last.data; + last = l; + size --; + return oldData; } public int size(){ return size; } - - public void addFirst(Object o){ - Node headNode=node(o); - headNode.data=o; - headNode.next=head.next; - head=headNode; - + + + public Iterator iterator() { + return new LinkedListIterator(); + } + + private class LinkedListIterator implements Iterator{ + private Node pointer = head; + private int nextIndex = 0; + + @Override + public boolean hasNext() { + return nextIndex < size; + } + + @Override + public Object next() { + if (!hasNext()) + throw new NoSuchElementException(); + Object nodeData = pointer.data; + pointer = pointer.next; + nextIndex ++; + return nodeData; + } + } + + private static class Node { + Object data; + Node next; + Node(Object data, Node next) { + this.data = data; + this.next = next; + } } - public void addLast(Object o){ - Node tailNode=head; - while(tailNode.next!=null){ - tailNode=tailNode.next; - } - Node lastNode=node(o); - tailNode.next=lastNode; - } - public Object removeFirst(){ - if (head==null) { - throw new NoSuchElementException(); - } - Object temp= head.data; - head=head.next; - size--; - return temp; - } - public Object removeLast(){ - if (head==null) { - throw new NoSuchElementException(); - } - Node newNode=head; - while(newNode.next.next!=null){ - newNode=newNode.next; - } - Node lastNode=newNode.next; - newNode.next=null; - size--; - return lastNode.data; - + /** + * Ѹ + * Ϊ 3->7->10 , úΪ 10->7->3 + */ + public void reverse() { + Node node = last; + Node preNode = head; + last = head; + head = node; + node = preNode.next; + Node nextNode; + preNode.next = null; + while (node != null) { + nextNode = node.next; + node.next = preNode; + preNode = node; + node = nextNode; + } } - public Iterator iterator(){ - return null; + + /** + * ɾһǰ벿 + * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + */ + public void removeFirstHalf() { + int half = size / 2; + Node node = head; + while (half != 0 ) { + head = head.next; + node.next = null; + node = head; + half --; + } } + /** + * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * @param i + * @param length + */ + public void remove(int i, int length) { + if (i + length != size) + makeSure(i + length); + Node node = head; + Node preNode = head; + + if (i > 0) { + for (int j = 0; j < i; ++j) { + preNode = node; + node = node.next; + } + } + + Node tempNode; + for (int j = 0; j < length; ++j) { + tempNode = node.next; + node.next = null; + node = tempNode; + size --; + } + + if (i == 0) { + head = node; + } else { + preNode.next = node; + } + } + /** + * ٶǰlistе + * ӵǰȡЩlistָԪ + * 統ǰ = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * صĽӦ[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list) { + int array[] = new int[list.size()]; + int index = 0; + int i = 0; + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + i = (int)iterator.next(); + makeSure(i); + array[index ++] = (int)get(i); + } + return array; + } - private static class Node{ - Object data; - Node next; - + /** + * ֪еԪֵУԵ洢ṹ + * ӵǰɾlistгֵԪ + * + * (list ListӼ) + * @param list + */ + public void subtract(LinkedList list) { + Iterator iterator = list.iterator(); + int index = 0; + Object element; + while (iterator.hasNext()) { + element = iterator.next(); + for (int i = index; i < size; ++i) { + if (element == get(i)) { + index = i; + break; + } + } + remove(index); + } } + + + /** + * 赱ǰͲlistָԪֵУͬһеԪֵͬ + * ҪCԪΪǰlistԪصĽұCеԪֵ + * @param list + */ + public LinkedList intersection( LinkedList list) { + LinkedList newLink = new LinkedList(); + Iterator it1 = iterator(); + Iterator it2 = list.iterator(); + int element1 = (int)it1.next(); + int element2 = (int)it2.next(); + while (it1.hasNext() && it2.hasNext()) { + if (element1 < element2) { + newLink.add(element1); + element1 = (int) it1.next(); + } else { + newLink.add(element2); + element2 = (int) it2.next(); + } + } + + while (it1.hasNext()) { + if (element1 == 0) + element1 = (int)it1.next(); + newLink.add(element1); + element1 = 0; + } + while (it2.hasNext()) { + if (element2 == 0) + element2 = (int)it2.next(); + newLink.add(element2); + element2 = 0; + } + if (element1 < element2) + newLink.add(element2); + else if (element2 < element1) + newLink.add(element1); + + return newLink; + } + public static void main(String[] args) { LinkedList linkedList=new LinkedList(); diff --git a/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/.gitignore b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/.gitignore new file mode 100644 index 0000000000..2c93a035dc --- /dev/null +++ b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/.gitignore @@ -0,0 +1,27 @@ +*.class +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#ide config +.metadata +.recommenders +.idea/ +*.iml +rebel.* +.rebel.* + +# Idea +*.iml +*.ipr +*.iws +.idea + +target diff --git a/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/DownloadThread.java b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/DownloadThread.java new file mode 100644 index 0000000000..c7da0ca056 --- /dev/null +++ b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/DownloadThread.java @@ -0,0 +1,44 @@ +package com.github.xiaozi123.coding2017.thirdWork; + +import java.io.IOException; + +import com.github.xiaozi123.coding2017.thirdWork.api.Connection; + + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + + + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + CyclicBarrier barrier; + String localFile; + public DownloadThread(Connection conn, int startPos, int endPos,String localFile,CyclicBarrier barrier){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + public void run(){ + try { + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + byte [] data = conn.read(startPos, endPos); + System.out.println("һȡļĶ"); + RandomAccessFile file = new RandomAccessFile(localFile,"rw"); + file.seek(startPos); + System.out.println("Ҫд"); + file.write(data); + file.close(); + conn.close(); + System.out.println(this.currentThread().getName()+"once over"); + barrier.await(); + } catch (Exception e) { + // TODO: handle exception + } + } +} diff --git a/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/FileDownloader.java b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/FileDownloader.java new file mode 100644 index 0000000000..1084c9aaac --- /dev/null +++ b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/FileDownloader.java @@ -0,0 +1,117 @@ +package com.github.xiaozi123.coding2017.thirdWork; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.github.xiaozi123.coding2017.thirdWork.api.Connection; +import com.github.xiaozi123.coding2017.thirdWork.api.ConnectionException; +import com.github.xiaozi123.coding2017.thirdWork.api.ConnectionManager; +import com.github.xiaozi123.coding2017.thirdWork.api.DownloadListener; + +public class FileDownloader { + private String url; + private String localFile; + DownloadListener listener; + ConnectionManager cm; + + private static final int DOWNLOAD_THREAD_NUM = 3; + public FileDownloader(String _url){ + this.url = _url; +// this.localFile = localFile; + } + + public void execute(){ + // ʵĴ룬 ע⣺ Ҫö߳ʵ + // ӿڣҪд⼸ӿڵʵִ + // 1 ConnectionManager ԴһӣͨConnectionԶȡеһΣStartPos,endPosָ + // 2DownloadListener, Ƕ߳أĿͻ˲֪ʲôʱҪʵ̶ִֵ߳Ժ󣬵listenernotifiedFinishedͻ˾յ֪ͨ + // ʵ˼· + // 1. ҪConnectionManager open ӣȻͨ Connection.getContentLengthļij + // 2. 3߳أעÿ߳ҪȵConnectionManageropen + // Ȼ read read жȡļĿʼλúͽλõIJֵbyte[] + // 3. byte д뵽ļ + // 4.е̶߳ԺҪ listener notifiedFinished + + // Ĵʵ룬Ҳ˵ֻһ̣߳Ҫɶ̵߳ + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM,new Runnable() {// еThread awaitʱִк barrierAction,ú߳ + @Override + public void run() { + listener.notifyFinished(); + } + }); + + Connection conn = null; + try { + conn = cm.open(this.url); + int length = conn.getContentLength();// õҪļij + createPlaceHolderFile(this.localFile,length);//ռλ + System.out.println("ռλ"); + int [][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM,length);// ÿ̷߳俪ʼλúͽλ + // ʼļ + System.out.println("ʼļ"); + for(int i = 0; i < DOWNLOAD_THREAD_NUM; i++){ + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + thread.start(); + System.out.println("" + (i+1) + "߳Ѿ"); + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + System.out.println("ر"); + if(conn != null){ + conn.close(); + System.out.println("رӳɹ"); + } + } + } + + public void setListener(DownloadListener listener){ + this.listener = listener; + } + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + public DownloadListener getListener(){ + return this.listener; + } + private void createPlaceHolderFile(String fileName,int contentLen) throws IOException{ + RandomAccessFile file = new RandomAccessFile(fileName,"rw"); + for(int i = 0; i < contentLen; i++){ + file.write(0); + } + file.close(); + } + /** + * ߳ļȣһά飬ÿ߳صĿʼλúͽλ + * @param threadNum + * @param contentLen + * @return + */ + private int [][] allocateDownloadRange(int threadNum, int contentLen){ + int [][] ranges = new int[threadNum][2];// öάÿ̵߳Ŀʼλúͽλ + + int eachThreadSize = contentLen / threadNum;// ÿ߳ҪصļС + int left = contentLen % threadNum;// ʣµĹһ߳ + + for(int i = 0; i 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 (Exception e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + } + +} diff --git a/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/impl/ConnectionManagerImpl.java b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..edc92dfbf7 --- /dev/null +++ b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/impl/ConnectionManagerImpl.java @@ -0,0 +1,17 @@ +package com.github.xiaozi123.coding2017.thirdWork.impl; + +import java.net.MalformedURLException; +import java.net.URL; + +import com.github.xiaozi123.coding2017.thirdWork.api.Connection; +import com.github.xiaozi123.coding2017.thirdWork.api.ConnectionException; +import com.github.xiaozi123.coding2017.thirdWork.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git "a/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/\346\226\207\347\253\240\345\234\260\345\235\200.txt" "b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/\346\226\207\347\253\240\345\234\260\345\235\200.txt" new file mode 100644 index 0000000000..5c09311e90 --- /dev/null +++ "b/group24/1054283210/src/com/github/xiaozi123/coding2017/thirdWork/\346\226\207\347\253\240\345\234\260\345\235\200.txt" @@ -0,0 +1 @@ +http://www.jianshu.com/p/e5a2cdc5d4e5 \ No newline at end of file diff --git a/group24/1148285693/.gitignore b/group24/1148285693/.gitignore index 8e0951ea09..23f75414d3 100644 --- a/group24/1148285693/.gitignore +++ b/group24/1148285693/.gitignore @@ -33,4 +33,6 @@ logs # other *.bak .directory -.DS_Store \ No newline at end of file +.DS_Store + +Test.java \ No newline at end of file diff --git a/group24/1148285693/learning2017/.editorconfig b/group24/1148285693/learning2017/.editorconfig new file mode 100644 index 0000000000..29c9408cf8 --- /dev/null +++ b/group24/1148285693/learning2017/.editorconfig @@ -0,0 +1,16 @@ +# indicate this is the root of the project +root = true + +[*] +indent_style = space +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +indent_size = 4 + +[*.html] +indent_size = 4 +max_line_length = 80 + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0312/basic/LinkedList.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0312/basic/LinkedList.java index 7b12d27c6c..e3cd7e9fa1 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0312/basic/LinkedList.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0312/basic/LinkedList.java @@ -18,15 +18,31 @@ public class LinkedList implements List { private static class Node { Object data; Node next; +// int intData; public Node(Object data, Node next) { this.data = data; this.next = next; } - +// public Node(Object data, Node next, int i) { +// this.data = data; +// this.next = next; +// this.intData = i; +// } } +// public void add(int i) { +// if (first == null) { +// first = new Node(null, null, i); +// last = first; +// } else { +// Node n = new Node(null, null, i); +// last.next = n; +// last = n; +// } +// size = size + 1; +// } public void add(Object o) { if (first == null) { first = new Node(o, null); @@ -38,6 +54,18 @@ public void add(Object o) { } size = size + 1; } +// +// public void addInt(int i) { +// if (first == null) { +// first = new Node(null, null, i); +// last = first; +// } else { +// Node n = new Node(null, null, i); +// last.next = n; +// last = n; +// } +// size = size + 1; +// } public void add(int index, Object o) throws IndexOutOfBoundsException { @@ -72,16 +100,20 @@ public void add(int index, Object o) throws IndexOutOfBoundsException { } - - public Object get(int index) { - if (index < 0 || index >= size) { + private Node getNode(int index){ + if (size == 0 || index < 0 || index >= size) { throw new IndexOutOfBoundsException("index boom"); } Node result = first; for (int i = 0; i < index; i++) { result = result.next; } - return result.data; + return result; + } + + + public Object get(int index) { + return getNode(index).data; } @@ -126,6 +158,13 @@ public Object remove(int index) { return result.data; } + + + + + + + public int size() { return size; } @@ -190,6 +229,23 @@ public Object next() { */ public void reverse() { + //还可以用堆栈 先进后出 + + if(size() <= 1){ + return; + } + Object[] array = new Object[size]; + Node tmp = first; + for (int i = 0; i < size; i++) { + array[i] = tmp.data; + tmp = tmp.next; + } + this.first = null; + this.last = null; + for (int i = array.length - 1; i >= 0 ; i--) { + add(array[i]); + } + } /** @@ -199,6 +255,13 @@ public void reverse() { */ public void removeFirstHalf() { + if (size <= 1){ + return; + } + int b = size/ 2; + Node n = getNode(b); + this.first = n; + size = (size % 2) + b; } /** @@ -208,7 +271,32 @@ public void removeFirstHalf() { * @param length */ public void remove(int i, int length) { + if (size == 0 || i < 0 || i >= size){ + return; + } + + length = size - i >= length ? length : size - i; + + if(i + length == size){ + this.first = null; + this.last = null; + size = 0; + return; + } + + if(i == 0){ + Node n = getNode(length); + first = n; + size = size - length; + return; + } + + + Node a = getNode(i - 1); + Node b = getNode(i + length); + a.next = b; + size = size - length; } /** @@ -220,8 +308,37 @@ public void remove(int i, int length) { * * @param list */ - public static int[] getElements(LinkedList list) { - return null; + public int[] getElements(LinkedList list) { + + if(size <= 0 || list.size() <= 0){ + return new int[0]; + } + + + + int[] result = new int[list.size()]; + + Node tmp = list.first; + int index = 0; + Node tmp2 = first; + for (int i = 0; i < list.size(); i++) { + int newIndex = (int)tmp.data; + int maxJ = newIndex - index; + for (int j = 0; j <= maxJ; j++) { + + if(j == maxJ){ + result[i] = (int)tmp2.data; + break; + } + tmp2 = tmp2.next; + } + index = newIndex; + tmp = tmp.next; + } + + size = size - list.size(); + + return result; } /** @@ -232,14 +349,56 @@ public static int[] getElements(LinkedList list) { */ public void subtract(LinkedList list) { + for (int i = 0; i < list.size(); i++) { + this.remove(list.get(i)); + } + + } + + + public void remove(Object obj){ + if(size <= 0){ + return; + } + if(first.data.equals(obj)){ + first=first.next; + size = size - 1; + return; + } + Node tmp = first; + Node tmp2 = first.next; + for (int i = 1; i < size; i++) { + if(tmp2.data.equals(obj)){ + tmp.next = tmp2.next; + size = size - 1; + return; + } + tmp = tmp.next; + tmp2 = tmp2.next; + } } + /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues() { + if(size <= 1){ + return; + } + + Node tmp = first; + for (int i = 1; i < size; i++) { + if(tmp.next == null){ + break; + } + if (tmp.data.equals(tmp.next.data)){ + tmp.next = tmp.next.next; + } + tmp = tmp.next; + } } @@ -251,7 +410,45 @@ public void removeDuplicateValues() { * @param max */ public void removeRange(int min, int max) { + if(size <= 0){ + return; + } + + Node tmp = first; + int a = -1; + int b = -1; + for (int i = 0; i < size; i++) { + if((int)tmp.data > min && a == -1){ + a = i; + } + + if((int)tmp.data >= max && b == -1){ + b = i; + } + + tmp = tmp.next; + } + + + if(min < max){ + remove(a, b - a); + return; + + } + + + if(min == max){ + + } + + if(min > max){ + + } + + + + return; } /** @@ -261,6 +458,53 @@ public void removeRange(int min, int max) { * @param list */ public LinkedList intersection(LinkedList list) { - return null; + LinkedList result = new LinkedList(); + + if(list == null || list.size <= 0 || size <= 0){ + return result; + } + + int i1 = 0; + int i2 = 0; + + while( i1 < this.size && i2 lenth){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, lenth); + } + + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + + CloseableHttpResponse response; + try { + response = httpClient.execute(httpget); + } catch (IOException e) { + e.printStackTrace(); + + return -1; + } + + HttpEntity httpEntity = response.getEntity(); + return (int) httpEntity.getContentLength(); + } + + @Override + public void close() { + + } + + + + + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0326/download/impl/ConnectionManagerImpl.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0326/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..e341546897 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/homework0326/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,17 @@ +package me.lzb.homework0326.download.impl; + + +import me.lzb.homework0326.download.api.Connection; +import me.lzb.homework0326.download.api.ConnectionException; +import me.lzb.homework0326.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0312/basic/LinkedListTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0312/basic/LinkedListTest.java index 0d48c290f1..ef0e043a11 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0312/basic/LinkedListTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0312/basic/LinkedListTest.java @@ -1,7 +1,5 @@ package me.lzb.homework0312.basic; -import me.lzb.homework0312.basic.Iterator; -import me.lzb.homework0312.basic.LinkedList; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -17,6 +15,8 @@ public class LinkedListTest { private LinkedList linkedList; + private LinkedList intList; + private String[] strArray; @Rule @@ -31,14 +31,26 @@ public void instantiate() throws Exception { linkedList.add("d"); strArray = new String[]{"a", "b", "c", "d"}; + + intList = new LinkedList(); + intList.add(0); + intList.add(1); + intList.add(2); + intList.add(3); + intList.add(4); + intList.add(5); + intList.add(6); + intList.add(7); + intList.add(8); + } @Test - public void iteratoreTest(){ + public void iteratoreTest() { Iterator iterator = linkedList.iterator(); int a = 0; - while (iterator.hasNext()){ + while (iterator.hasNext()) { Assert.assertEquals(strArray[a], iterator.next().toString()); a = a + 1; } @@ -105,4 +117,142 @@ public void addIndexTest() throws IndexOutOfBoundsException { } + @Test + public void reverseTest() { + linkedList.reverse(); + Assert.assertEquals("[d,c,b,a]", linkedList.toString()); + } + + @Test + public void removeFirstHalfTest() { + intList.removeFirstHalf(); + Assert.assertEquals("[4,5,6,7,8]", intList.toString()); + Assert.assertEquals(5, intList.size()); + linkedList.removeFirstHalf(); + Assert.assertEquals("[c,d]", linkedList.toString()); + Assert.assertEquals(2, linkedList.size()); + } + + @Test + public void removeITest() { + intList.remove(0, 10); + Assert.assertEquals("[]", intList.toString()); + Assert.assertEquals(0, intList.size()); + + + linkedList.remove(1, 2); + Assert.assertEquals("[a,d]", linkedList.toString()); + Assert.assertEquals(2, linkedList.size()); + + + LinkedList l = new LinkedList(); + l.add("a"); + l.add("b"); + l.add("c"); + l.add("d"); + l.remove(0, 2); + Assert.assertEquals("[c,d]", l.toString()); + Assert.assertEquals(2, l.size()); + } + + + @Test + public void getElementsTest() { + int[] a = {1, 3, 4, 6}; + + LinkedList l = new LinkedList(); + l.add(1); + l.add(3); + l.add(4); + l.add(6); + int[] re = intList.getElements(l); + + Assert.assertEquals(a.length, re.length); + for (int i = 0; i < a.length; i++) { + Assert.assertEquals(a[i], re[i]); + } + + } + + + @Test + public void subtractTest() { + LinkedList l = new LinkedList(); + l.add(1); + l.add(3); + l.add(4); + l.add(6); + intList.subtract(l); + Assert.assertEquals(5, intList.size()); + Assert.assertEquals("[0,2,5,7,8]", intList.toString()); + } + + + @Test + public void removeDuplicateValuesTest() { + LinkedList list = new LinkedList(); + list.add(1); + list.add(1); + list.add(2); + list.add(2); + list.add(3); + list.add(5); + list.add(5); + list.add(6); + list.removeDuplicateValues(); + + Assert.assertEquals("[1,2,3,5,6]", list.toString()); + } + + + @Test + public void removeRangeTest() { + { + LinkedList linkedList = new LinkedList(); + + linkedList.add(11); + linkedList.add(12); + linkedList.add(13); + linkedList.add(14); + linkedList.add(16); + linkedList.add(16); + linkedList.add(19); + + linkedList.removeRange(10, 19); + Assert.assertEquals("[19]", linkedList.toString()); + } + + { + LinkedList linkedList = new LinkedList(); + + linkedList.add(11); + linkedList.add(12); + linkedList.add(13); + linkedList.add(14); + linkedList.add(16); + linkedList.add(16); + linkedList.add(19); + + linkedList.removeRange(10, 14); + Assert.assertEquals("[14,16,16,19]", linkedList.toString()); + } + } + + + @Test + public void intersectionTest() { + LinkedList list1 = new LinkedList(); + list1.add(1); + list1.add(6); + list1.add(7); + + LinkedList list2 = new LinkedList(); + list2.add(2); + list2.add(5); + list2.add(6); + + LinkedList newList = list1.intersection(list2); + Assert.assertEquals("[6]", newList.toString()); + } + } diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0326/download/ConnectionTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0326/download/ConnectionTest.java new file mode 100644 index 0000000000..10eb296623 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0326/download/ConnectionTest.java @@ -0,0 +1,55 @@ +package me.lzb.homework0326.download; + +import me.lzb.homework0326.download.api.Connection; +import me.lzb.homework0326.download.api.ConnectionManager; +import me.lzb.homework0326.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by LZB on 2017/3/27. + */ +public class ConnectionTest { + + private static final String imageUrl = "https://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-499994.png"; + + + @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(imageUrl); + Assert.assertEquals(35470, conn.getContentLength()); + } + + @Test + public void testRead() throws Exception{ + + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open(imageUrl); + + 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); + + + // 测试不充分,没有断言内容是否正确 + } +} diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0326/download/FileDownloaderTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0326/download/FileDownloaderTest.java new file mode 100644 index 0000000000..c1c459184f --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/homework0326/download/FileDownloaderTest.java @@ -0,0 +1,60 @@ +package me.lzb.homework0326.download; + +import me.lzb.homework0326.download.api.ConnectionManager; +import me.lzb.homework0326.download.api.DownloadListener; +import me.lzb.homework0326.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class FileDownloaderTest { + + private static final String imageUrl = "https://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-499994.png"; + + boolean downloadFinished = false; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + + FileDownloader downloader = new FileDownloader(imageUrl, "D:\\code\\learning\\tmp\\test.jpg"); + + + 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/group24/1148285693/learning2017/pom.xml b/group24/1148285693/learning2017/pom.xml index 4951c1ff42..29ff362b6f 100644 --- a/group24/1148285693/learning2017/pom.xml +++ b/group24/1148285693/learning2017/pom.xml @@ -102,6 +102,13 @@ 1.10 + + + org.apache.httpcomponents + httpclient + 4.5.3 + + diff --git a/group24/120509419/JUnitTest/download/FileDownloaderTest.java b/group24/120509419/JUnitTest/download/FileDownloaderTest.java new file mode 100644 index 0000000000..5d68c4d24e --- /dev/null +++ b/group24/120509419/JUnitTest/download/FileDownloaderTest.java @@ -0,0 +1,97 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import static java.lang.System.in; +import java.math.BigInteger; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import javaclass.download.api.ConnectionManager; +import javaclass.download.api.DownloadListener; +import javaclass.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author CJ + */ +public class FileDownloaderTest { + + boolean downloadFinished = false; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() throws IOException, NoSuchAlgorithmException { + + String url = "http://pineappledb.xyz/test.txt"; + + FileDownloader downloader = new FileDownloader(url); + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + downloader.setOutputFile(new File("C:\\Users\\CJ\\Desktop\\test000.txt")); + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + File downloadFile = downloader.getOutputFile(); + File expectedFile = new File("C:\\Users\\CJ\\Desktop\\test.txt"); + + long downloadSize = downloadFile.length(); + long expectedSize = expectedFile.length(); + + Assert.assertEquals(expectedSize, downloadSize); + FileInputStream downloadin = new FileInputStream(downloadFile); + FileInputStream expectedin = new FileInputStream(expectedFile); + + + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(downloadin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, downloadFile.length())); + BigInteger downloadbi = new BigInteger(1, md5.digest()); + md5.update(expectedin.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, expectedFile.length())); + BigInteger expectedbi = new BigInteger(1,md5.digest()); + Assert.assertEquals(downloadbi, expectedbi); + + } + +} diff --git a/group24/120509419/javaclass/download/DownloadThread.java b/group24/120509419/javaclass/download/DownloadThread.java new file mode 100644 index 0000000000..addc6a03c2 --- /dev/null +++ b/group24/120509419/javaclass/download/DownloadThread.java @@ -0,0 +1,70 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javaclass.download.api.Connection; + +public class DownloadThread extends Thread { + + Connection conn; + int startPos; + int endPos; + + int curStepByteSize = 1024*8; +// byte[] stepByteArr; + + public File getCurTmpFile() { + return curTmpFile; + } + File curTmpFile; + + public DownloadThread(Connection conn, int startPos, int endPos) { + +// stepByteArr = new byte[curStepByteSize]; + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; +// curTmpFile = + } + + @Override + public void run() { + + try { + curTmpFile = File.createTempFile("TBtools", "downloadTmp"); +// BufferedWriter bw = new BufferedWriter(new FileWriter(curTmpFile)); + FileOutputStream fos = new FileOutputStream(curTmpFile); + + + // 一个线程 内 分批次下载,这样才不会挤爆内存 +// int size = endPos - startPos+1; +// int stepCount = size / curStepByteSize; +//// ssint remainSize = size % curStepByteSize; +// for (int i = 0; i < stepCount-1; i++) { +// fos.write(conn.read(startPos+curStepByteSize*i, startPos+curStepByteSize*(i+1)-1)); +// System.err.printf("Start Pos: %d\tEnd Pos %d\n",startPos+curStepByteSize*i, startPos+curStepByteSize*(i+1)-1); +// } + +// fos.write(conn.read(startPos+curStepByteSize*(stepCount-1),endPos)); +// System.err.printf("Start Pos: %d\tEnd Pos %d\n",startPos+curStepByteSize*(stepCount-1), endPos); + + fos.write(conn.read(startPos, endPos)); + + + fos.close(); + } catch (IOException ex) { + Logger.getLogger(DownloadThread.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/group24/120509419/javaclass/download/FileDownloader.java b/group24/120509419/javaclass/download/FileDownloader.java new file mode 100644 index 0000000000..b30826a72a --- /dev/null +++ b/group24/120509419/javaclass/download/FileDownloader.java @@ -0,0 +1,129 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javaclass.download.api.Connection; +import javaclass.download.api.ConnectionException; +import javaclass.download.api.ConnectionManager; +import javaclass.download.api.DownloadListener; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + private int numOfThreads = 2; + + public File getOutputFile() { + return outputFile; + } + + public void setOutputFile(File outputFile) { + this.outputFile = outputFile; + } + + private File outputFile; + + + 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 { + // 针对每个线程,重新打开一个连接 + conn = cm.open(this.url); + + int length = conn.getContentLength(); + System.err.println("Total Length:"+length); + int threadSize = length / numOfThreads; +// int remainSize = length % numOfThreads; + int threadCount = 0; + ExecutorService fixedThreadPool = Executors.newFixedThreadPool(numOfThreads); + DownloadThread[] dtArr = new DownloadThread[numOfThreads]; + for (int i = 0; i < numOfThreads-1; i++) { + conn = cm.open(this.url); + System.err.println("Thread "+threadCount++); + dtArr[i] = new DownloadThread(conn, i * threadSize, (i + 1) * threadSize - 1); + fixedThreadPool.submit(dtArr[i]); + } + conn = cm.open(this.url); + dtArr[numOfThreads-1] = new DownloadThread(conn,(numOfThreads-1) * threadSize, length - 1); + fixedThreadPool.submit(dtArr[numOfThreads-1]); + fixedThreadPool.shutdown(); + // 提交之后,等到 365天 + fixedThreadPool.awaitTermination(365, TimeUnit.DAYS); + + // 合并所有文件 + FileOutputStream fos = new FileOutputStream(outputFile); + for(DownloadThread curDt:dtArr){ + FileInputStream fis = new FileInputStream(curDt.getCurTmpFile()); + byte[] bufferedByteArr = new byte[1024*8]; + int readSize; + while((readSize=fis.read(bufferedByteArr))!=-1){ + fos.write(bufferedByteArr, 0, readSize); + } + fis.close(); + } + fos.close(); + + listener.notifyFinished(); + } catch (ConnectionException e) { + e.printStackTrace(); + } catch (InterruptedException ex) { + Logger.getLogger(FileDownloader.class.getName()).log(Level.SEVERE, null, ex); + } catch (FileNotFoundException ex) { + Logger.getLogger(FileDownloader.class.getName()).log(Level.SEVERE, null, ex); + } 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/group24/120509419/javaclass/download/api/Connection.java b/group24/120509419/javaclass/download/api/Connection.java new file mode 100644 index 0000000000..96d7df5d5e --- /dev/null +++ b/group24/120509419/javaclass/download/api/Connection.java @@ -0,0 +1,28 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.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/group24/120509419/javaclass/download/api/ConnectionException.java b/group24/120509419/javaclass/download/api/ConnectionException.java new file mode 100644 index 0000000000..5b8eb530dd --- /dev/null +++ b/group24/120509419/javaclass/download/api/ConnectionException.java @@ -0,0 +1,14 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download.api; + +/** + * + * @author CJ + */ +public class ConnectionException extends Exception { + +} \ No newline at end of file diff --git a/group24/120509419/javaclass/download/api/ConnectionManager.java b/group24/120509419/javaclass/download/api/ConnectionManager.java new file mode 100644 index 0000000000..8f0caeabd7 --- /dev/null +++ b/group24/120509419/javaclass/download/api/ConnectionManager.java @@ -0,0 +1,22 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download.api; + +/** + * + * @author CJ + */ +public interface ConnectionManager { + + /** + * 给定一个url , 打开一个连接 + * + * @param url + * @return + * @throws javaclass.download.api.ConnectionException + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group24/120509419/javaclass/download/api/DownloadListener.java b/group24/120509419/javaclass/download/api/DownloadListener.java new file mode 100644 index 0000000000..45d63dfa79 --- /dev/null +++ b/group24/120509419/javaclass/download/api/DownloadListener.java @@ -0,0 +1,14 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download.api; + +/** + * + * @author CJ + */ +public interface DownloadListener { + public void notifyFinished(); +} \ No newline at end of file diff --git a/group24/120509419/javaclass/download/impl/ConnectionImpl.java b/group24/120509419/javaclass/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..b14f2faaea --- /dev/null +++ b/group24/120509419/javaclass/download/impl/ConnectionImpl.java @@ -0,0 +1,60 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download.impl; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.net.URLConnection; +import javaclass.download.api.Connection; + +public class ConnectionImpl implements Connection { + + private URLConnection uc; + private int curPos; +// private ; + BufferedInputStream bis; + public ConnectionImpl(URLConnection uc) throws IOException{ + this.uc = uc; + this.curPos = 0; + bis = new BufferedInputStream(uc.getInputStream()); + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + // 调整位置 +// bis.skip(startPos-this.curPos+1); +// bis.skip(startPos-this.curPos); +// this.curPos = endPos; + + // 因为只会read一次 + bis.skip(startPos); + + int readSize = endPos - startPos+1; + byte[] bufferedByte = new byte[readSize]; + + + int getSize = bis.read(bufferedByte); + System.err.println("Start Pos And End Pos:"+startPos+"\t"+endPos); + System.err.println("expected Size:"+readSize); + System.err.println("Get Size:"+getSize); + + return bufferedByte; +// = ; +// return Arrays.copyOfRange(bufferedByte, 0, getSize); + } + + @Override + public int getContentLength() { + + return uc.getContentLength(); + } + + @Override + public void close() { + + } + +} diff --git a/group24/120509419/javaclass/download/impl/ConnectionManagerImpl.java b/group24/120509419/javaclass/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..4388fc17f7 --- /dev/null +++ b/group24/120509419/javaclass/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download.impl; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; +import javaclass.download.api.Connection; +import javaclass.download.api.ConnectionException; +import javaclass.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + try { + URL curUrl = new URL(url); + ConnectionImpl ConnectionImpl = new ConnectionImpl(curUrl.openConnection()); + + return ConnectionImpl; + } catch (MalformedURLException ex) { + Logger.getLogger(ConnectionManagerImpl.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(ConnectionManagerImpl.class.getName()).log(Level.SEVERE, null, ex); + } + return null; + } + +} diff --git a/group24/120509419/javaclass/download/impl/Test.java b/group24/120509419/javaclass/download/impl/Test.java new file mode 100644 index 0000000000..b3a9d9f985 --- /dev/null +++ b/group24/120509419/javaclass/download/impl/Test.java @@ -0,0 +1,23 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package javaclass.download.impl; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * + * @author CJ + */ +public class Test { + public static void main(String[] args) throws FileNotFoundException, IOException { + File curFile = new File("http://www.baidu.com"); + RandomAccessFile raf = new RandomAccessFile(curFile,"r"); + System.err.println(raf.length()); + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/LinkedList.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/LinkedList.java index d10c40a563..7afb0e5500 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/basic/LinkedList.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/LinkedList.java @@ -171,7 +171,18 @@ private static class Node{ * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ - + if(null==head){ + return; + } + Node tempNode=new Node(); + Node currentNode=head.next; + head.next=null; + while(null!=currentNode){ + tempNode=currentNode.next; + currentNode.next=head; + head=currentNode; + currentNode=tempNode; + } } /** @@ -181,7 +192,17 @@ public void reverse(){ */ public void removeFirstHalf(){ - + if(null==head){ + return; + } + Node tempNode; + int size=size(); + size=size/2; + for(int i=0;i=oriSize){ + break; + } + temp=next-temp; + for(int i=0;inext){ + continue; + } + if(currentNode==head){ + head=head.next; + }else{ + preNode.next=currentNode.next; + } + tempNode=currentNode; + currentNode=currentNode.next; + tempNode.next=null; + if(null==currentNode){ + break; + } + tempData=(Integer)currentNode.data; + } } /** @@ -220,17 +319,91 @@ public void subtract(LinkedList list){ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ - + Node currentNode=head; + Node tempNode=head; + int tempData; + while(null!=currentNode && null!=currentNode.next){ + tempData=(Integer)currentNode.data; + if(tempData==(Integer)currentNode.next.data){ + if(null!=currentNode.next.next){ + tempNode=currentNode.next; + currentNode.next=currentNode.next.next; + tempNode.next=null; + }else{ + currentNode.next=null; + } + }else{ + currentNode=currentNode.next; + } + } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * 试写一高效的算法,删除表中所有值大于等于min且小于等于max的元素(若表中存在这样的元素) * @param min * @param max */ public void removeRange(int min, int max){ - + if(null==head){ + return; + } + int size=size(); + int headData=(Integer)head.data; + int endData=(Integer)get(size-1); + if(headData>=min && endData<=max){ + head=null; + return; + } + if(headData>max || endData=arm){ + return beginIndex; + } + tempData=(Integer)get(endIndex); + if(tempData<=arm){ + return endIndex; + } + int middleIndex=0; + while(beginIndexarm){ + endIndex=middleIndex; + }else{ + break; + } + } + return middleIndex; } /** @@ -239,6 +412,31 @@ public void removeRange(int min, int max){ * @param list */ public LinkedList rsection( LinkedList list){ - return null; + LinkedList armList=new LinkedList(); + Node tempNode=head; + if(null==list || list.size()==0){ + while(null!=tempNode){ + armList.add(tempNode.data); + tempNode=tempNode.next; + } + }else{ + Iterator iterator = list.iterator(); + Integer next; + Integer data; + while(iterator.hasNext()){ + next = (Integer)iterator.next(); + while(null!=tempNode){ + data = (Integer)tempNode.data; + if(data 0){ + FileInputStream fileInputStream =new FileInputStream(file); + InputStreamReader inputStreamReader =new InputStreamReader(fileInputStream); + BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + String content = bufferedReader.readLine(); + int currentPosition = Integer.parseInt(content); + startIndex = currentPosition; + } + + int endIndex = (threadId+1)*blockSize-1; + if(threadId == threadCount-1){ + endIndex = length-1; + } + Connection connection = cm.open(url); + new DownloadThread(connection,startIndex,endIndex,threadId,listener).start(); + } + } + + 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/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/FileDownloaderTest.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..10e9dbfa46 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/FileDownloaderTest.java @@ -0,0 +1,66 @@ +package com.github.ipk2015.coding2017.coderising.download; + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.ipk2015.coding2017.coderising.download.api.ConnectionManager; +import com.github.ipk2015.coding2017.coderising.download.api.DownloadListener; +import com.github.ipk2015.coding2017.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://dldir1.qq.com/qqfile/qq/QQ8.9.1/20437/QQ8.9.1.exe"; + int threadCount=3; + FileDownloader downloader = new FileDownloader(url,threadCount); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + System.out.println("下载完成啦"); + } + + }); + + + try { + downloader.execute(); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + // 等待多线程下载程序执行完毕 +// while (!downloadFinished) { +// try { +// System.out.println("还没有下载完成,休眠五秒"); +// //休眠5秒 +// Thread.sleep(5000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// } +// System.out.println("下载完成!"); + + } + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/Connection.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/Connection.java new file mode 100644 index 0000000000..c7a61ac781 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/Connection.java @@ -0,0 +1,32 @@ +package com.github.ipk2015.coding2017.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; + /** + * 给定开始和结束位置, 读取数据,适用于多线程下载 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public void read(int startPos,int endPos,int threadId,DownloadListener listener) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/ConnectionException.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..780ed30029 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.github.ipk2015.coding2017.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/ConnectionManager.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..cfa76e4ea6 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.github.ipk2015.coding2017.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/DownloadListener.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..97ceef6416 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.github.ipk2015.coding2017.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/impl/ConnectionImpl.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..bf60948390 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,97 @@ +package com.github.ipk2015.coding2017.coderising.download.impl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; + +import com.github.ipk2015.coding2017.coderising.download.api.Connection; +import com.github.ipk2015.coding2017.coderising.download.api.DownloadListener; + + +public class ConnectionImpl implements Connection{ + private String path; + public static int threadCount=0; + public ConnectionImpl(String path){ + super(); + this.path=path; + } + + + @Override + public int getContentLength() { + URL url; + int length=0; + try { + url = new URL(path); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(3000); + int code = conn.getResponseCode(); + System.out.println("code:"+code+""); + if(code == 200){ + // 获得服务器端文件的大小 + length = conn.getContentLength(); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return length; + } + + @Override + public void close() { + + + } + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + return null; + } + + + @Override + public void read(int startPos, int endPos,int threadId,DownloadListener listener) throws IOException { + URL url=new URL(path); + HttpURLConnection conn=(HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(3000); + conn.setRequestProperty("Range", "bytes="+startPos+"-"+endPos); + int code=conn.getResponseCode(); + if(code==206){ + InputStream inputStream = conn.getInputStream(); + int lastIndexOf = path.lastIndexOf("/"); + RandomAccessFile randomAccessFile = new RandomAccessFile(path.substring(lastIndexOf+1),"rwd"); + RandomAccessFile tempPositionFile = new RandomAccessFile(threadId+".txt","rwd"); + randomAccessFile.seek(startPos); + int length=-1,total=0; + byte[] buffer=new byte[1024*500]; + while((length=inputStream.read(buffer))!=-1){ + randomAccessFile.write(buffer,0,length); + total=total+length; + tempPositionFile.write(((startPos+total)+"").getBytes()); + } + tempPositionFile.close(); + randomAccessFile.close(); + inputStream.close(); + synchronized (ConnectionImpl.class) { + //把当前线程的临时文件删除 + File file = new File(threadId+".txt"); + if(file.exists()){ + file.delete(); + } + threadCount--; + if(threadCount==0){ + listener.notifyFinished(); + } + } + } + } + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/impl/ConnectionManagerImpl.java b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..50169258f1 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,18 @@ +package com.github.ipk2015.coding2017.coderising.download.impl; + +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; + +import com.github.ipk2015.coding2017.coderising.download.api.Connection; +import com.github.ipk2015.coding2017.coderising.download.api.ConnectionException; +import com.github.ipk2015.coding2017.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + Connection conn=new ConnectionImpl(url); + return conn; + } +} diff --git a/group24/1525619747/homework_20170312/src/com/basic/ArrayList.java b/group24/1525619747/homework_20170312/src/com/basic/ArrayList.java index 008b390255..d60c6b8c0c 100644 --- a/group24/1525619747/homework_20170312/src/com/basic/ArrayList.java +++ b/group24/1525619747/homework_20170312/src/com/basic/ArrayList.java @@ -9,36 +9,29 @@ public class ArrayList implements List private Object[] elementData = new Object[MAXNSIZE]; - public void add(Object o) - { - if (size > MAXNSIZE) - { + public void add(Object o) { + if (size > MAXNSIZE) { String errorInfo = "Out of max size" + MAXNSIZE; throw new ArrayIndexOutOfBoundsException(errorInfo); } elementData[size++] = o; } - public void add(int index, Object o) - { - if (index >= size && size > 0) - { + public void add(int index, Object o) { + if (index >= size && size > 0) { String errorInfo = "Index to add: " + index + " is out of current size: " + size; throw new ArrayIndexOutOfBoundsException(errorInfo); } - for (int i = size; i > index; i--) - { + for (int i = size; i > index; i--) { elementData[i] = elementData[i - 1]; } elementData[index] = o; ++size; } - public Object get(int index) - { - if (index < 0 || index >= size) - { + public Object get(int index) { + if (index < 0 || index >= size) { String errorInfo = "Index to get: " + index + " is invalid, current range: 0 - " + (size - 1); throw new ArrayIndexOutOfBoundsException(errorInfo); @@ -46,45 +39,36 @@ public Object get(int index) return elementData[index]; } - public Object remove(int index) - { - if (index < 0 || index >= size) - { + public Object remove(int index) { + if (index < 0 || index >= size) { String errorInfo = "Index to remove: " + index + " is invalid, current range: 0 - " + (size - 1); throw new ArrayIndexOutOfBoundsException(errorInfo); } Object o = elementData[index]; - for (int i = index; i < size - 1; i++) - { + for (int i = index; i < size - 1; i++) { elementData[i] = elementData[i + 1]; } elementData[size--] = null; return o; } - public int size() - { + public int size() { return size; } - public Iterator iterator() - { - return new Iterator() - { + public Iterator iterator() { + return new Iterator() { private int index = 0; - public boolean hasNext() - { + public boolean hasNext() { return (index < size); } - public Object next() - { - if (hasNext()) - { + public Object next() { + if (hasNext()) { return elementData[index++]; } return null; diff --git a/group24/1525619747/homework_20170312/src/com/basic/BinaryTreeNode.java b/group24/1525619747/homework_20170312/src/com/basic/BinaryTreeNode.java index 63899d38ce..543b8bfb85 100644 --- a/group24/1525619747/homework_20170312/src/com/basic/BinaryTreeNode.java +++ b/group24/1525619747/homework_20170312/src/com/basic/BinaryTreeNode.java @@ -7,75 +7,57 @@ public class BinaryTreeNode private BinaryTreeNode left; private BinaryTreeNode right; - public BinaryTreeNode (Object data) - { + public BinaryTreeNode (Object data) { this.data = data; left = null; right = null; } public BinaryTreeNode (Object data, BinaryTreeNode left, - BinaryTreeNode right) - { + BinaryTreeNode right) { this.data = data; this.left = left; this.right = right; } - public Object getData() - { + public Object getData() { return data; } - public void setData(Object data) - { + public void setData(Object data) { this.data = data; } - public BinaryTreeNode getLeft() - { + public BinaryTreeNode getLeft() { return left; } - public void setLeft(BinaryTreeNode left) - { + public void setLeft(BinaryTreeNode left) { this.left = left; } - public BinaryTreeNode getRight() - { + public BinaryTreeNode getRight() { return right; } - public void setRight(BinaryTreeNode right) - { + public void setRight(BinaryTreeNode right) { this.right = right; } /* * 排序二叉树的插入 */ - public BinaryTreeNode insert(Object o) - { - if (((Integer) data) > ((Integer) o)) - { - if (left == null) - { + public BinaryTreeNode insert(Object o) { + if (((Integer) data) > ((Integer) o)) { + if (left == null) { setLeft(new BinaryTreeNode(o)); - } - else - { + } else { left.insert(o); } - } - else - { - if (right == null) - { + } else { + if (right == null) { setRight(new BinaryTreeNode(o)); - } - else - { + } else { right.insert(o); } } @@ -85,17 +67,14 @@ public BinaryTreeNode insert(Object o) /* * 前序遍历 */ - public void preOrderInterator() - { - if (left != null) - { + public void preOrderInterator() { + if (left != null) { left.preOrderInterator(); } System.out.print(data.toString() + " "); - if (right != null) - { + if (right != null) { right.preOrderInterator(); } } diff --git a/group24/1525619747/homework_20170312/src/com/basic/LinkedList.java b/group24/1525619747/homework_20170312/src/com/basic/LinkedList.java index e741421aad..61be6bd5f6 100644 --- a/group24/1525619747/homework_20170312/src/com/basic/LinkedList.java +++ b/group24/1525619747/homework_20170312/src/com/basic/LinkedList.java @@ -5,17 +5,12 @@ public class LinkedList implements List private Node head; - public void add(Object o) - { - if (head == null) - { + public void add(Object o) { + if (head == null) { head = new Node(o, null); - } - else - { + } else { Node nodePointer = head; - while (nodePointer.next != null) - { + while (nodePointer.next != null) { nodePointer = nodePointer.next; } nodePointer.next = new Node(o, null); @@ -23,30 +18,25 @@ public void add(Object o) } - public void add(int index, Object o) - { + public void add(int index, Object o) { int size = size(); - if (index < 0 || index > size) - { + if (index < 0 || index > size) { String errorInfo = "Invalid index to add:" + index + " out of range: [0," + size + "]"; throw new ArrayIndexOutOfBoundsException(errorInfo); } int step = 0; Node nodePointer = head; - while (step < index) - { + while (step < index) { nodePointer = nodePointer.next; ++step; } nodePointer.next = new Node(o, nodePointer.next); } - public Object get(int index) - { + public Object get(int index) { int size = size(); - if (index < 0 || index > size) - { + if (index < 0 || index > size) { String errorInfo = "Invalid index to get:" + index + " out of range: [0," + size + "]"; throw new ArrayIndexOutOfBoundsException(errorInfo); @@ -54,8 +44,7 @@ public Object get(int index) int step = 0; Node nodePointer = head; - while (step < index) - { + while (step < index) { nodePointer = nodePointer.next; ++step; } @@ -63,11 +52,9 @@ public Object get(int index) return nodePointer.data; } - public Object remove(int index) - { + public Object remove(int index) { int size = size(); - if (index < 0 || index > size) - { + if (index < 0 || index > size) { String errorInfo = "Invalid index to remove:" + index + " out of range: [0," + size + "]"; throw new ArrayIndexOutOfBoundsException(errorInfo); @@ -77,8 +64,7 @@ public Object remove(int index) Node nodePointer = head; Node lastPointer = head; - while (step < index) - { + while (step < index) { lastPointer = nodePointer; nodePointer = nodePointer.next; ++step; @@ -86,15 +72,12 @@ public Object remove(int index) Object o = null; - if (lastPointer == nodePointer) - { + if (lastPointer == nodePointer) { Node toDelete = head; o = toDelete.data; head = head.next; toDelete = null; - } - else - { + } else { o = nodePointer.data; lastPointer.next = nodePointer.next; nodePointer = null; @@ -103,15 +86,12 @@ public Object remove(int index) return o; } - public int size() - { + public int size() { int size = 0; - if (head != null) - { + if (head != null) { ++size; Node nodePointer = head; - while (nodePointer.next != null) - { + while (nodePointer.next != null) { ++size; nodePointer = nodePointer.next; } @@ -119,37 +99,30 @@ public int size() return size; } - public void addFirst(Object o) - { - if (head == null) - { + public void addFirst(Object o) { + if (head == null) { head = new Node(o, null); return; } head = new Node(o, head); } - public void addLast(Object o) - { - if (head == null) - { + public void addLast(Object o) { + if (head == null) { head = new Node(o, null); return; } Node nodePointer = head; - while (nodePointer.next != null) - { + while (nodePointer.next != null) { nodePointer = nodePointer.next; } nodePointer.next = new Node(o, null); } @SuppressWarnings ("unused") - public Object removeFirst() - { - if (head == null) - { + public Object removeFirst() { + if (head == null) { return null; } @@ -161,18 +134,15 @@ public Object removeFirst() return o; } - public Object removeLast() - { - if (head == null) - { + public Object removeLast() { + if (head == null) { return null; } Node nodePointer = head; Node lastPointer = head; - while (nodePointer.next != null) - { + while (nodePointer.next != null) { lastPointer = nodePointer; nodePointer = nodePointer.next; } @@ -183,24 +153,19 @@ public Object removeLast() return o; } - public Iterator iterator() - { - return new Iterator() - { + public Iterator iterator() { + return new Iterator() { private Node nodePointer = head; - public boolean hasNext() - { + public boolean hasNext() { // TODO Auto-generated method stub return (nodePointer != null); } - public Object next() - { + public Object next() { // TODO Auto-generated method stub - if (hasNext()) - { + if (hasNext()) { Object o = nodePointer.data; nodePointer = nodePointer.next; return o; @@ -215,8 +180,7 @@ private static class Node Object data; Node next; - public Node (Object o, Node n) - { + public Node (Object o, Node n) { this.data = o; this.next = n; } @@ -225,16 +189,13 @@ public Node (Object o, Node n) /** * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ - public void reverse() - { - if (head == null) - { + public void reverse() { + if (head == null) { return; } Node reverse = null; - while (size() > 0) - { + while (size() > 0) { reverse = new Node(removeFirst(), reverse); } @@ -246,13 +207,11 @@ public void reverse() * ,删除以后的值为7,8,10 */ @SuppressWarnings ("unused") - public void removeFirstHalf() - { + public void removeFirstHalf() { int removeLength = size() / 2; int step = 0; Node toDelete = null; - while (step < removeLength) - { + while (step < removeLength) { toDelete = head; head = head.next; toDelete = null; @@ -266,18 +225,15 @@ public void removeFirstHalf() * @param i * @param length */ - public void remove(int i, int length) - { + public void remove(int i, int length) { int size = size(); - if (i >= size) - { + if (i >= size) { return; } Node nodePointer = head; Node lastPointer = head; int step = 0; - while (step < i) - { + while (step < i) { lastPointer = nodePointer; nodePointer = nodePointer.next; ++step; @@ -285,20 +241,15 @@ public void remove(int i, int length) step = 0; Node toDelete = null; - if (lastPointer == head) - { - while (step < length) - { + if (lastPointer == head) { + while (step < length) { toDelete = head; head = head.next; toDelete = null; ++step; } - } - else - { - while (step < length) - { + } else { + while (step < length) { toDelete = nodePointer; nodePointer = nodePointer.next; toDelete = null; @@ -316,13 +267,11 @@ public void remove(int i, int length) * * @param list */ - public int[] getElements(LinkedList list) - { + public int[] getElements(LinkedList list) { int[] elements = new int[list.size()]; Iterator it = list.iterator(); int index = 0; - for (; it.hasNext();) - { + for (; it.hasNext();) { elements[index++] = (Integer) get((Integer) (it.next())); } return elements; @@ -334,29 +283,22 @@ public int[] getElements(LinkedList list) * @param list */ - public void subtract(LinkedList list) - { - if (head == null) - { + public void subtract(LinkedList list) { + if (head == null) { return; } Node nodePointer = head; Node lastPointer = head; Node toDelte = null; - while (nodePointer != null) - { - if (list.contain(nodePointer.data)) - { - if (nodePointer == head) - { + while (nodePointer != null) { + if (list.contain(nodePointer.data)) { + if (nodePointer == head) { toDelte = head; head = head.next; toDelte = null; nodePointer = head; lastPointer = head; - } - else - { + } else { toDelte = nodePointer; lastPointer.next = nodePointer.next; toDelte = null; @@ -368,13 +310,10 @@ public void subtract(LinkedList list) } - private boolean contain(Object o) - { + private boolean contain(Object o) { Node nodePointer = head; - while (nodePointer != null) - { - if (nodePointer.data.equals(o)) - { + while (nodePointer != null) { + if (nodePointer.data.equals(o)) { return true; } nodePointer = nodePointer.next; @@ -385,20 +324,17 @@ private boolean contain(Object o) /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ - public void removeDuplicateValues() - { + public void removeDuplicateValues() { Node nodePointer = head; - if (nodePointer.next == null) - { + if (nodePointer.next == null) { return; } Node toDelete = null; - while (nodePointer.next != null) - { + while (nodePointer.next != null) { while (nodePointer.next != null - && nodePointer.data.equals(nodePointer.next.data)) - { // delete nodePointer.next + && nodePointer.data.equals(nodePointer.next.data)) { // delete + // nodePointer.next toDelete = nodePointer.next; nodePointer.next = nodePointer.next.next; toDelete = null; @@ -413,34 +349,27 @@ public void removeDuplicateValues() * @param min * @param max */ - public void removeRange(int min, int max) - { + public void removeRange(int min, int max) { Node nodePointer = head; Node lastPointer = head; - if (nodePointer == null) - { + if (nodePointer == null) { return; } while (nodePointer != null - && ((Integer) nodePointer.data) <= (new Integer(min))) - { + && ((Integer) nodePointer.data) <= (new Integer(min))) { lastPointer = nodePointer; nodePointer = nodePointer.next; } Node toDelete = null; while (nodePointer != null - && ((Integer) nodePointer.data) < (new Integer(max))) - { - if (nodePointer == head) - { + && ((Integer) nodePointer.data) < (new Integer(max))) { + if (nodePointer == head) { toDelete = head; head = head.next; toDelete = null; nodePointer = head; lastPointer = head; - } - else - { + } else { toDelete = nodePointer; lastPointer.next = nodePointer.next; nodePointer = nodePointer.next; @@ -455,39 +384,30 @@ public void removeRange(int min, int max) * * @param list */ - public LinkedList intersection(LinkedList list) - { + public LinkedList intersection(LinkedList list) { LinkedList linkedList = new LinkedList(); Iterator it1 = iterator(); Iterator it2 = list.iterator(); Object o1 = null; Object o2 = null; - if (size() == 0 || list.size() == 0) - { + if (size() == 0 || list.size() == 0) { return null; } o1 = it1.next(); o2 = it2.next(); - while (o1 != null && o2 != null) - { + while (o1 != null && o2 != null) { // System.out.println(o1 + " " + o2); - if (((Integer) o1) == ((Integer) o2)) - { + if (((Integer) o1) == ((Integer) o2)) { linkedList.add(o1); o1 = it1.next(); o2 = it2.next(); - } - else - { - if (((Integer) o1) > ((Integer) o2)) - { + } else { + if (((Integer) o1) > ((Integer) o2)) { o2 = it2.next(); - } - else - { + } else { o1 = it1.next(); } } diff --git a/group24/1525619747/homework_20170312/src/com/basic/Queue.java b/group24/1525619747/homework_20170312/src/com/basic/Queue.java index b040c85722..67cde6b46b 100644 --- a/group24/1525619747/homework_20170312/src/com/basic/Queue.java +++ b/group24/1525619747/homework_20170312/src/com/basic/Queue.java @@ -4,23 +4,19 @@ public class Queue { private LinkedList list = new LinkedList(); - public void enQueue(Object o) - { + public void enQueue(Object o) { list.addLast(o); } - public Object deQueue() - { + public Object deQueue() { return list.removeFirst(); } - public boolean isEmpty() - { + public boolean isEmpty() { return (list.size() == 0); } - public int size() - { + public int size() { return list.size(); } } diff --git a/group24/1525619747/homework_20170312/src/com/basic/Stack.java b/group24/1525619747/homework_20170312/src/com/basic/Stack.java index db7ada4c53..09fe1a6f7d 100644 --- a/group24/1525619747/homework_20170312/src/com/basic/Stack.java +++ b/group24/1525619747/homework_20170312/src/com/basic/Stack.java @@ -4,28 +4,23 @@ public class Stack { private ArrayList elementData = new ArrayList(); - public void push(Object o) - { + public void push(Object o) { elementData.add(0, o); } - public Object pop() - { + public Object pop() { return elementData.remove(0); } - public Object peek() - { + public Object peek() { return elementData.get(0); } - public boolean isEmpty() - { + public boolean isEmpty() { return (elementData.size() == 0); } - public int size() - { + public int size() { return elementData.size(); } } diff --git a/group24/1525619747/homework_20170312/src/testcase/TestArrayList.java b/group24/1525619747/homework_20170312/src/testcase/TestArrayList.java index 134a541265..643333b851 100644 --- a/group24/1525619747/homework_20170312/src/testcase/TestArrayList.java +++ b/group24/1525619747/homework_20170312/src/testcase/TestArrayList.java @@ -11,27 +11,19 @@ public class TestArrayList { @Test - public void testAdd() - { + public void testAdd() { ArrayList list = new ArrayList(); - try - { + try { list.add(3); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } assertTrue(list.get(0).equals(3)); - try - { - for (int i = 0; i < 100; i++) - { + try { + for (int i = 0; i < 100; i++) { list.add(i); } - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); // System.out.println(e.getMessage()); assertEquals("100", e.getMessage()); @@ -43,21 +35,16 @@ public void testAdd() * test add(index, o) */ @Test - public void testIndexAdd() - { + public void testIndexAdd() { ArrayList list = new ArrayList(); - try - { - for (int i = 0; i < 10; i++) - { + try { + for (int i = 0; i < 10; i++) { list.add(i); } list.add(3, 20); list.add(0, 30); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } @@ -71,15 +58,11 @@ public void testIndexAdd() assertTrue(list.get(4).equals(20)); assertTrue(list.get(5).equals(3)); - try - { - for (int i = 0; i < 100; i++) - { + try { + for (int i = 0; i < 100; i++) { list.add(i, i); } - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); // System.out.println(e.getMessage()); assertEquals("100", e.getMessage()); @@ -90,35 +73,24 @@ public void testIndexAdd() * test get(index) */ @Test - public void testGet() - { + public void testGet() { ArrayList list = new ArrayList(); - try - { - for (int i = 0; i < 10; i++) - { + try { + for (int i = 0; i < 10; i++) { list.add(i); } - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } - try - { + try { list.get(0); list.get(5); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } - try - { + try { list.get(10); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); // System.out.println(e.getMessage()); // System.out.println(list.size()); @@ -132,60 +104,44 @@ public void testGet() * test remove(index) and size */ @Test - public void testRemove() - { + public void testRemove() { ArrayList list = new ArrayList(); - try - { - for (int i = 0; i < 10; i++) - { + try { + for (int i = 0; i < 10; i++) { list.add(i); } assertTrue(list.size() == 10); list.remove(3); assertTrue(list.size() == 9); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } assertFalse(list.get(3).equals(3)); assertTrue(list.get(3).equals(4)); - try - { + try { list.remove(-3); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); // System.out.println(e.getMessage()); } - try - { + try { list.remove(20); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); // System.out.println(e.getMessage()); } } @Test - public void testInterator() - { + public void testInterator() { ArrayList list = new ArrayList(); - try - { - for (int i = 0; i < 10; i++) - { + try { + for (int i = 0; i < 10; i++) { list.add(i); } - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } diff --git a/group24/1525619747/homework_20170312/src/testcase/TestBinaryTreeNode.java b/group24/1525619747/homework_20170312/src/testcase/TestBinaryTreeNode.java index 472b9a7fb0..fa934ec025 100644 --- a/group24/1525619747/homework_20170312/src/testcase/TestBinaryTreeNode.java +++ b/group24/1525619747/homework_20170312/src/testcase/TestBinaryTreeNode.java @@ -7,8 +7,7 @@ public class TestBinaryTreeNode { @Test - public void testBinaryTree() - { + public void testBinaryTree() { BinaryTreeNode binNode = new BinaryTreeNode(5); binNode.insert(1); binNode.insert(10); diff --git a/group24/1525619747/homework_20170312/src/testcase/TestLinkedList.java b/group24/1525619747/homework_20170312/src/testcase/TestLinkedList.java index 05ac118a90..0b733821a4 100644 --- a/group24/1525619747/homework_20170312/src/testcase/TestLinkedList.java +++ b/group24/1525619747/homework_20170312/src/testcase/TestLinkedList.java @@ -14,8 +14,7 @@ public class TestLinkedList * test add() and size() */ @Test - public void testAdd() - { + public void testAdd() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); @@ -23,8 +22,7 @@ public void testAdd() } @Test - public void testGet() - { + public void testGet() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); @@ -32,12 +30,9 @@ public void testGet() assertFalse(linkedList.get(0).equals("hello world")); assertTrue(linkedList.get(1).equals("hello world")); - try - { + try { linkedList.get(-1); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); String errorInfo = "Invalid index to get:" + -1 + " out of range: [0," + linkedList.size() + "]"; @@ -47,32 +42,25 @@ public void testGet() } @Test - public void testRemove() - { + public void testRemove() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); linkedList.add(4); linkedList.add("Leon Deng"); - try - { + try { linkedList.remove(-1); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); String errorInfo = "Invalid index to remove:" + -1 + " out of range: [0," + linkedList.size() + "]"; assertTrue(e.getMessage().equals(errorInfo)); } - try - { + try { linkedList.remove(10); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNotNull(e); String errorInfo = "Invalid index to remove:" + 10 + " out of range: [0," + linkedList.size() + "]"; @@ -80,22 +68,16 @@ public void testRemove() } Object o = null; - try - { + try { o = linkedList.remove(0); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } assertTrue(o.equals(3)); - try - { + try { o = linkedList.remove(2); - } - catch (ArrayIndexOutOfBoundsException e) - { + } catch (ArrayIndexOutOfBoundsException e) { assertNull(e); } // System.out.println(o); @@ -103,8 +85,7 @@ public void testRemove() } @Test - public void testAddFirst() - { + public void testAddFirst() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); @@ -115,8 +96,7 @@ public void testAddFirst() } @Test - public void testAddLast() - { + public void testAddLast() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); @@ -126,8 +106,7 @@ public void testAddLast() } @Test - public void testRemoveFirst() - { + public void testRemoveFirst() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); @@ -139,8 +118,7 @@ public void testRemoveFirst() } @Test - public void testRemoveLast() - { + public void testRemoveLast() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("hello world"); @@ -153,8 +131,7 @@ public void testRemoveLast() } @Test - public void testInterator() - { + public void testInterator() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add("Leon Deng"); @@ -168,8 +145,7 @@ public void testInterator() } @Test - public void testReverse() - { + public void testReverse() { LinkedList linkedList = new LinkedList(); linkedList.add(3); linkedList.add(4); @@ -210,8 +186,7 @@ public void testReverse() } @Test - public void testRemoveFirstHalf() - { + public void testRemoveFirstHalf() { LinkedList linkedList = new LinkedList(); linkedList.add(2); linkedList.add(5); @@ -239,8 +214,7 @@ public void testRemoveFirstHalf() } @Test - public void testRemoveIndexLength() - { + public void testRemoveIndexLength() { LinkedList linkedList = new LinkedList(); linkedList.add(2); linkedList.add(5); @@ -271,8 +245,7 @@ public void testRemoveIndexLength() } @Test - public void testGetElements() - { + public void testGetElements() { // 11->101->201->301->401->501->601->701 listB = 1->3->4->6 LinkedList linkedList = new LinkedList(); linkedList.add(11); @@ -304,8 +277,7 @@ public void testGetElements() } @Test - public void testSubstract() - { + public void testSubstract() { LinkedList linkedList = new LinkedList(); linkedList.add(11); linkedList.add(101); @@ -336,8 +308,7 @@ public void testSubstract() } @Test - public void testRemoveDuplicateValues() - { + public void testRemoveDuplicateValues() { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(1); @@ -363,11 +334,9 @@ public void testRemoveDuplicateValues() } @Test - public void testRemoveRange() - { + public void testRemoveRange() { LinkedList linkedList = new LinkedList(); - for (int i = 0; i < 10; i++) - { + for (int i = 0; i < 10; i++) { linkedList.add(i); } @@ -383,8 +352,7 @@ public void testRemoveRange() } @Test - public void testIntersection() - { + public void testIntersection() { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(2); diff --git a/group24/1525619747/homework_20170312/src/testcase/TestQueue.java b/group24/1525619747/homework_20170312/src/testcase/TestQueue.java index 390238efc9..75b129ff17 100644 --- a/group24/1525619747/homework_20170312/src/testcase/TestQueue.java +++ b/group24/1525619747/homework_20170312/src/testcase/TestQueue.java @@ -12,14 +12,12 @@ public class TestQueue * test enQueue() isEmpty() and size() deQueue */ @Test - public void testQueue() - { + public void testQueue() { Queue queue = new Queue(); assertTrue(queue.isEmpty()); - for (int i = 10; i < 20; i++) - { + for (int i = 10; i < 20; i++) { queue.enQueue(i); } diff --git a/group24/1525619747/homework_20170312/src/testcase/TestStack.java b/group24/1525619747/homework_20170312/src/testcase/TestStack.java index 2091577ec1..bf91470c5c 100644 --- a/group24/1525619747/homework_20170312/src/testcase/TestStack.java +++ b/group24/1525619747/homework_20170312/src/testcase/TestStack.java @@ -9,14 +9,12 @@ public class TestStack { @Test - public void testStack() - { + public void testStack() { Stack stack = new Stack(); assertTrue(stack.isEmpty()); - for (int i = 10; i < 20; i++) - { + for (int i = 10; i < 20; i++) { stack.push(i); } diff --git a/group24/1525619747/homework_20170319/src/com/basic/ArrayUtil.java b/group24/1525619747/homework_20170319/src/com/basic/ArrayUtil.java index 9b4b81c12d..42b712f5bc 100644 --- a/group24/1525619747/homework_20170319/src/com/basic/ArrayUtil.java +++ b/group24/1525619747/homework_20170319/src/com/basic/ArrayUtil.java @@ -12,21 +12,18 @@ public class ArrayUtil * @param origin * @return */ - public void reverseArray(int[] origin) - { + public void reverseArray(int[] origin) { int length = origin.length; int left = 0; int right = length - 1; int a = 0; int b = 0; - while (left < right) - { + while (left < right) { swap(origin, left++, right--); } } - private void swap(int[] origin, int i, int j) - { + private void swap(int[] origin, int i, int j) { // TODO Auto-generated method stub int tmp = origin[i]; origin[i] = origin[j]; @@ -41,29 +38,23 @@ private void swap(int[] origin, int i, int j) * @return */ - public int[] removeZero(int[] oldArray) - { + public int[] removeZero(int[] oldArray) { int length = oldArray.length; int[] newArray = new int[length]; int[] zeroArray = new int[length]; int zIndex = 0; int nzIndex = 0; - for (int i = 0; i < length; i++) - { - if (oldArray[i] == 0) - { + for (int i = 0; i < length; i++) { + if (oldArray[i] == 0) { zeroArray[zIndex++] = oldArray[i]; - } - else - { + } else { newArray[nzIndex++] = oldArray[i]; } } int[] newArray2 = new int[nzIndex]; - for (int i = 0; i < nzIndex; i++) - { + for (int i = 0; i < nzIndex; i++) { newArray2[i] = newArray[i]; } @@ -79,8 +70,7 @@ public int[] removeZero(int[] oldArray) * @return */ - public int[] merge(int[] array1, int[] array2) - { + public int[] merge(int[] array1, int[] array2) { int length1 = array1.length; int length2 = array2.length; int[] array3 = new int[length1 + length2]; @@ -89,56 +79,46 @@ public int[] merge(int[] array1, int[] array2) int index2 = 0; int index3 = 0; - while (index1 < length1 && index2 < length2) - { + while (index1 < length1 && index2 < length2) { - if (index3 > 0) - { - if (array3[index3 - 1] == array1[index1]) - { + if (index3 > 0) { + if (array3[index3 - 1] == array1[index1]) { ++index1; continue; } - if (array3[index3 - 1] == array2[index2]) - { + if (array3[index3 - 1] == array2[index2]) { ++index2; continue; } } - if (array1[index1] == array2[index2]) - { + if (array1[index1] == array2[index2]) { array3[index3++] = array1[index1]; ++index1; ++index2; continue; } - if (array1[index1] < array2[index2]) - { + if (array1[index1] < array2[index2]) { array3[index3++] = array1[index1]; ++index1; continue; } - if (array1[index1] > array2[index2]) - { + if (array1[index1] > array2[index2]) { array3[index3++] = array2[index2]; ++index2; continue; } } - while (index1 < length1) - { + while (index1 < length1) { array3[index3++] = array1[index1++]; } - while (index2 < length2) - { + while (index2 < length2) { array3[index3++] = array1[index2++]; } int[] newArray = new int[index3]; - for (int i = 0; i < index3; i++) - { + for (int i = 0; i < index3; i++) { newArray[i] = array3[i]; } @@ -154,16 +134,13 @@ public int[] merge(int[] array1, int[] array2) * @param size * @return */ - public int[] grow(int[] oldArray, int size) - { + public int[] grow(int[] oldArray, int size) { int length = oldArray.length; int[] newArr = new int[length + size]; - for (int i = 0; i < length; i++) - { + for (int i = 0; i < length; i++) { newArr[i] = oldArray[i]; } - for (int i = length; i < length + size; i++) - { + for (int i = length; i < length + size; i++) { newArr[i] = 0; } return newArr; @@ -176,10 +153,8 @@ public int[] grow(int[] oldArray, int size) * @param max * @return */ - public int[] fibonacci(int max) - { - if (max == 1) - { + public int[] fibonacci(int max) { + if (max == 1) { return null; } int[] arr = new int[max / 2]; @@ -191,8 +166,7 @@ public int[] fibonacci(int max) arr[1] = 1; int index = 2; - while (a + b < max) - { + while (a + b < max) { arr[index++] = a + b; c = b; b = a + b; @@ -200,8 +174,7 @@ public int[] fibonacci(int max) } int[] newArr = new int[index]; - for (int i = 0; i < index; i++) - { + for (int i = 0; i < index; i++) { newArr[i] = arr[i]; } @@ -214,34 +187,27 @@ public int[] fibonacci(int max) * @param max * @return */ - public int[] getPrimes(int max) - { + public int[] getPrimes(int max) { int size = max / 2 + 1; int[] arr = new int[size]; int index = 0; - for (int i = 2; i < max; i++) - { - if (isPrime(i)) - { + for (int i = 2; i < max; i++) { + if (isPrime(i)) { arr[index++] = i; } } int[] newArr = new int[index]; - for (int i = 0; i < index; i++) - { + for (int i = 0; i < index; i++) { newArr[i] = arr[i]; } return newArr; } - public boolean isPrime(int i) - { - for (int j = 2; j < i / 2; j++) - { - if (i % j == 0) - { + public boolean isPrime(int i) { + for (int j = 2; j < i / 2; j++) { + if (i % j == 0) { return false; } } @@ -254,35 +220,28 @@ public boolean isPrime(int i) * @param max * @return */ - public int[] getPerfectNumbers(int max) - { + public int[] getPerfectNumbers(int max) { int size = max / 2 + 1; int[] arr = new int[size]; int index = 0; - for (int i = 2; i < max; i++) - { - if (isPerfectNumber(i)) - { + for (int i = 2; i < max; i++) { + if (isPerfectNumber(i)) { arr[index++] = i; } } int[] newArr = new int[index]; - for (int i = 0; i < index; i++) - { + for (int i = 0; i < index; i++) { newArr[i] = arr[i]; } return newArr; } - public boolean isPerfectNumber(int num) - { + public boolean isPerfectNumber(int num) { int sum = 0; - for (int i = 1; i <= num / 2; i++) - { - if (num % i == 0) - { + for (int i = 1; i <= num / 2; i++) { + if (num % i == 0) { sum += i; } } @@ -297,12 +256,10 @@ public boolean isPerfectNumber(int num) * @param s * @return */ - public String join(int[] array, String seperator) - { + public String join(int[] array, String seperator) { String str = ""; int length = array.length; - for (int a : array) - { + for (int a : array) { str += a + seperator; } str = str.substring(0, str.length() - 1); diff --git a/group24/1525619747/homework_20170319/src/com/struts/DomXmlHelper.java b/group24/1525619747/homework_20170319/src/com/struts/DomXmlHelper.java index 31d27b592c..4683947920 100644 --- a/group24/1525619747/homework_20170319/src/com/struts/DomXmlHelper.java +++ b/group24/1525619747/homework_20170319/src/com/struts/DomXmlHelper.java @@ -21,22 +21,17 @@ public class DomXmlHelper private Map kv = new HashMap(); - public DomXmlHelper () throws DocumentException - { + public DomXmlHelper () throws DocumentException { fetchAttributes(); } // 遍历当前节点下的所有节点 - private void listNodes(Element node, String loop, Map kv) - { + private void listNodes(Element node, String loop, Map kv) { // System.out.println("当前节点的名称:" + node.getName()); - if (loop.equals("")) - { + if (loop.equals("")) { loop += node.getName(); - } - else - { + } else { kv.put(loop, node.getName()); loop += "-" + node.getName(); } @@ -44,8 +39,7 @@ private void listNodes(Element node, String loop, Map kv) // 首先获取当前节点的所有属性节点 List list = node.attributes(); // 遍历属性节点 - for (Attribute attribute : list) - { + for (Attribute attribute : list) { // System.out.println("属性 "+attribute.getName() +":" + // attribute.getValue()); kv.put(loop, attribute.getValue()); @@ -54,8 +48,7 @@ private void listNodes(Element node, String loop, Map kv) } // 如果当前节点内容不为空,则输出 - if (!(node.getTextTrim().equals(""))) - { + if (!(node.getTextTrim().equals(""))) { // System.out.println("内容 " + node.getName() + ":" + // node.getText()); kv.put(loop, node.getText()); @@ -66,15 +59,13 @@ private void listNodes(Element node, String loop, Map kv) // 同时迭代当前节点下面的所有子节点 // 使用递归 Iterator iterator = node.elementIterator(); - while (iterator.hasNext()) - { + while (iterator.hasNext()) { Element e = iterator.next(); listNodes(e, loop, kv); } } - private void fetchAttributes() throws DocumentException - { + private void fetchAttributes() throws DocumentException { // 创建SAXReader对象 SAXReader reader = new SAXReader(); // 读取文件 转换成Document @@ -86,23 +77,20 @@ private void fetchAttributes() throws DocumentException listNodes(root, "", kv); - for (Map.Entry entity : kv.entrySet()) - { + for (Map.Entry entity : kv.entrySet()) { // System.out.println("key: " + entity.getKey() + " , value: " + // entity.getValue()); } } - public String getActionView(String action, String method) - { + public String getActionView(String action, String method) { String key = "struts-action-" + action; String className = kv.get(key); key += "-" + className + "-result-" + method; return kv.get(key); } - public String getActionClassByName(String action) - { + public String getActionClassByName(String action) { String key = "struts-action-" + action; return kv.get(key); } diff --git a/group24/1525619747/homework_20170319/src/com/struts/LoginAction.java b/group24/1525619747/homework_20170319/src/com/struts/LoginAction.java index 6d1d5a2ca6..91527ca78e 100644 --- a/group24/1525619747/homework_20170319/src/com/struts/LoginAction.java +++ b/group24/1525619747/homework_20170319/src/com/struts/LoginAction.java @@ -12,21 +12,17 @@ public class LoginAction private String password; private String message; - public String getName() - { + public String getName() { return name; } - public String getPassword() - { + public String getPassword() { return password; } - public String execute() - { + public String execute() { System.out.println("name: " + name + " , password: " + password); - if ("test".equals(name) && "1234".equals(password)) - { + if ("test".equals(name) && "1234".equals(password)) { this.message = "login successful"; return "success"; } @@ -34,18 +30,15 @@ public String execute() return "fail"; } - public void setName(String name) - { + public void setName(String name) { this.name = name; } - public void setPassword(String password) - { + public void setPassword(String password) { this.password = password; } - public String getMessage() - { + public String getMessage() { return this.message; } } diff --git a/group24/1525619747/homework_20170319/src/com/struts/Struts.java b/group24/1525619747/homework_20170319/src/com/struts/Struts.java index f0ff145909..af2a5ce5c0 100644 --- a/group24/1525619747/homework_20170319/src/com/struts/Struts.java +++ b/group24/1525619747/homework_20170319/src/com/struts/Struts.java @@ -16,8 +16,7 @@ public static View runAction(String actionName, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, - NoSuchFieldException - { + NoSuchFieldException { /* * @@ -45,8 +44,7 @@ public static View runAction(String actionName, class1 = Class.forName(className); // System.out.println("类名称 " + class1.getName()); - if (class1 != null) - { + if (class1 != null) { // 调用class1的setName方法, 待参数 // 根据.class反射出来的类实例 Object instance = class1.newInstance(); @@ -58,8 +56,7 @@ public static View runAction(String actionName, Object res2 = method.invoke(instance, "1234"); // set attr - for (Map.Entry entity : parameters.entrySet()) - { + for (Map.Entry entity : parameters.entrySet()) { String attrName = entity.getKey(); String attrValue = entity.getValue(); diff --git a/group24/1525619747/homework_20170319/src/com/struts/View.java b/group24/1525619747/homework_20170319/src/com/struts/View.java index b5b9e2802b..15125a7f04 100644 --- a/group24/1525619747/homework_20170319/src/com/struts/View.java +++ b/group24/1525619747/homework_20170319/src/com/struts/View.java @@ -7,24 +7,20 @@ public class View private String jsp; private Map parameters; - public String getJsp() - { + public String getJsp() { return jsp; } - public View setJsp(String jsp) - { + public View setJsp(String jsp) { this.jsp = jsp; return this; } - public Map getParameters() - { + public Map getParameters() { return parameters; } - public View setParameters(Map parameters) - { + public View setParameters(Map parameters) { this.parameters = parameters; return this; } diff --git a/group24/1525619747/homework_20170319/src/testcase/StrutsTest.java b/group24/1525619747/homework_20170319/src/testcase/StrutsTest.java index 61ef07748f..0f9f66b87b 100644 --- a/group24/1525619747/homework_20170319/src/testcase/StrutsTest.java +++ b/group24/1525619747/homework_20170319/src/testcase/StrutsTest.java @@ -18,8 +18,7 @@ public class StrutsTest public void testLoginActionSuccess() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException, DocumentException, NoSuchFieldException - { + InvocationTargetException, DocumentException, NoSuchFieldException { String actionName = "login"; @@ -38,8 +37,7 @@ public void testLoginActionSuccess() throws ClassNotFoundException, public void testLoginActionFailed() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException, DocumentException, NoSuchFieldException - { + InvocationTargetException, DocumentException, NoSuchFieldException { String actionName = "login"; Map params = new HashMap(); params.put("name", "test"); diff --git a/group24/1525619747/homework_20170319/src/testcase/TestArrayUtil.java b/group24/1525619747/homework_20170319/src/testcase/TestArrayUtil.java index fffa56eac1..7b7f69c570 100644 --- a/group24/1525619747/homework_20170319/src/testcase/TestArrayUtil.java +++ b/group24/1525619747/homework_20170319/src/testcase/TestArrayUtil.java @@ -8,10 +8,8 @@ public class TestArrayUtil { - private void print_r(int[] a) - { - for (int i = 0; i < a.length; i++) - { + private void print_r(int[] a) { + for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); } System.out.println(); @@ -25,8 +23,7 @@ private void print_r(int[] a) } @Test - public void testReverseArray() - { + public void testReverseArray() { ArrayUtil arrayUtil = new ArrayUtil(); int[] a = { 7, 9, 30, 3 }; @@ -50,8 +47,7 @@ public void testReverseArray() } @Test - public void testRemoveZero() - { + public void testRemoveZero() { ArrayUtil arrayUtil = new ArrayUtil(); int[] oldArr = { 1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 0, 5 }; @@ -63,8 +59,7 @@ public void testRemoveZero() } @Test - public void testMerge() - { + public void testMerge() { ArrayUtil arrayUtil = new ArrayUtil(); int[] a1 = { 3, 5, 7, 8 }; @@ -79,8 +74,7 @@ public void testMerge() } @Test - public void testGrow() - { + public void testGrow() { ArrayUtil arrayUtil = new ArrayUtil(); int[] a1 = { 3, 5, 7, 8 }; @@ -96,8 +90,7 @@ public void testGrow() } @Test - public void testFibonacci() - { + public void testFibonacci() { ArrayUtil arrayUtil = new ArrayUtil(); int max = 100; int[] arr = arrayUtil.fibonacci(max); @@ -112,8 +105,7 @@ public void testFibonacci() } @Test - public void testGetPrimes() - { + public void testGetPrimes() { ArrayUtil arrayUtil = new ArrayUtil(); int max = 23; int[] arr = arrayUtil.getPrimes(max); @@ -126,8 +118,7 @@ public void testGetPrimes() } @Test - public void testGetPerfectNumbers() - { + public void testGetPerfectNumbers() { ArrayUtil arrayUtil = new ArrayUtil(); int max = 300; int[] arr = arrayUtil.getPerfectNumbers(max); @@ -140,8 +131,7 @@ public void testGetPerfectNumbers() } @Test - public void testJoin() - { + public void testJoin() { ArrayUtil arrayUtil = new ArrayUtil(); int[] a = { 3, 8, 9 }; String str = arrayUtil.join(a, "-"); diff --git a/group24/1525619747/homework_20170328/src/com/coderising/download/DownloadThread.java b/group24/1525619747/homework_20170328/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..4c4ba75534 --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,107 @@ +package com.coderising.download; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread +{ + + Connection conn; + int startPos; + int endPos; + int length = 0; + String savePathDir; + String fileName; + + public DownloadThread (Connection conn, int startPos, int endPos) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.length = endPos - startPos + 1; + } + + public DownloadThread (Connection conn, int startPos, int endPos, + String savePathDir, String fileName) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.length = endPos - startPos + 1; + this.savePathDir = savePathDir; + this.fileName = fileName; + } + + public void run() { + System.out.println("thread " + this.getId() + " running..."); + + try { + byte[] data = null; + data = conn.read(startPos, endPos); + // 检验下载长度是否一致(即是否传输出错) + for (int i = 0; i < 5; i++) { + if (length != data.length) { + System.out.print("thread " + this.getId() + + " not equal ! Loop " + (i + 1)); + System.out.print(", length: " + length); + System.out.println(", downloaded: " + data.length); + data = conn.read(startPos, endPos); + } else { + break; + } + } + + saveFile(savePathDir, fileName, data, startPos); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private synchronized boolean saveFile(String savePathDir, String fileName, + byte[] data, int offset) { + System.out.println("thread " + this.getId() + " saveFile..."); + File saveDir = new File(savePathDir); + if (!saveDir.exists()) { + saveDir.mkdir(); + } + + synchronized (this) { + File file = new File(saveDir + File.separator + fileName); + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(file, "rw"); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + raf.seek(offset); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + raf.write(data); + return true; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + try { + if (raf != null) { + raf.close(); + } + } catch (IOException e) { + // + } + } + } + + return false; + } +} diff --git a/group24/1525619747/homework_20170328/src/com/coderising/download/FileDownloader.java b/group24/1525619747/homework_20170328/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..fad06f3e57 --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,124 @@ +package com.coderising.download; + +import java.awt.List; +import java.util.ArrayList; + +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 +{ + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + String savePathDir; + + String fileName; + + int threadNum = 5; + private ArrayList dtList = new ArrayList(); + + public FileDownloader (String _url) { + this.url = _url; + } + + public FileDownloader (String _url, String savePathDir, String fileName) { + this.url = _url; + this.savePathDir = savePathDir; + this.fileName = fileName; + } + + public FileDownloader (String _url, String savePathDir, String fileName, + int threadNum) { + this.url = _url; + this.savePathDir = savePathDir; + this.fileName = fileName; + this.threadNum = threadNum; + } + + 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(); + + int sectionLength = length / threadNum; + System.out.println("content length: " + length + + ", sectionLength: " + sectionLength); + + for (int i = 0; i < threadNum; i++) { + if (i == threadNum - 1) { + dtList.add(new DownloadThread(conn, sectionLength * i, + length - 1, this.savePathDir, this.fileName)); + } else { + dtList.add(new DownloadThread(conn, sectionLength * i, + sectionLength * (i + 1) - 1, this.savePathDir, + this.fileName)); + } + } + for (int i = 0; i < dtList.size(); i++) { + dtList.get(i).start(); + } + + // while (!isFinished()) { + // // block wait ? + // } + // if (isFinished()) { + // listener.notifyFinished(); + // } + + } catch (ConnectionException e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + + } + + public boolean isFinished() { + for (int i = 0; i < dtList.size(); i++) { + if (!dtList.get(i).getState().equals(Thread.State.TERMINATED)) { + return false; + } + } + return true; + } + + 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/group24/1525619747/homework_20170328/src/com/coderising/download/api/Connection.java b/group24/1525619747/homework_20170328/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..714efcf0df --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/api/Connection.java @@ -0,0 +1,29 @@ +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/group24/1525619747/homework_20170328/src/com/coderising/download/api/ConnectionException.java b/group24/1525619747/homework_20170328/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..5627d198b8 --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,6 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception +{ + +} diff --git a/group24/1525619747/homework_20170328/src/com/coderising/download/api/ConnectionManager.java b/group24/1525619747/homework_20170328/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..c7e9ab91cb --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,12 @@ +package com.coderising.download.api; + +public interface ConnectionManager +{ + /** + * 给定一个url , 打开一个连接 + * + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group24/1525619747/homework_20170328/src/com/coderising/download/api/DownloadListener.java b/group24/1525619747/homework_20170328/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..5e64145084 --- /dev/null +++ b/group24/1525619747/homework_20170328/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/group24/1525619747/homework_20170328/src/com/coderising/download/impl/ConnectionImpl.java b/group24/1525619747/homework_20170328/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..65367e80d2 --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,93 @@ +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.util.HashMap; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection +{ + + private String urlStr = null; + + public ConnectionImpl () { + } + + public ConnectionImpl (String url) { + this.urlStr = url; + } + + public byte[] read(int startPos, int endPos) throws IOException { + // 设置起始与终止位置 + URL url = null; + try { + url = new URL(this.urlStr); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + HttpURLConnection conn = null; + try { + conn = (HttpURLConnection) url.openConnection(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + conn.setConnectTimeout(3 * 1000); // 3s + conn.setReadTimeout(60 * 1000); + conn.setRequestProperty("User-Agent", + "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream inputStream = conn.getInputStream(); + + byte[] buffer = new byte[1024]; + int len = 0; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + while ((len = inputStream.read(buffer)) != -1) { + bos.write(buffer, 0, len); + } + + inputStream.close(); + bos.close(); + conn.disconnect(); + + return bos.toByteArray(); + } + + public int getContentLength() { + URL url = null; + try { + url = new URL(this.urlStr); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + HttpURLConnection conn = null; + try { + conn = (HttpURLConnection) url.openConnection(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + conn.setConnectTimeout(3 * 1000); // 3s + conn.setRequestProperty("User-Agent", + "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + + return conn.getContentLength(); + } + + public void close() { + + } + +} diff --git a/group24/1525619747/homework_20170328/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group24/1525619747/homework_20170328/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..f3e819fe4b --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,19 @@ +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 +{ + + public Connection open(String urlStr) throws ConnectionException { + return new ConnectionImpl(urlStr); + } + +} diff --git a/group24/1525619747/homework_20170328/src/com/coderising/helper/Tool.java b/group24/1525619747/homework_20170328/src/com/coderising/helper/Tool.java new file mode 100644 index 0000000000..b4e56334e4 --- /dev/null +++ b/group24/1525619747/homework_20170328/src/com/coderising/helper/Tool.java @@ -0,0 +1,59 @@ +package com.coderising.helper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class Tool +{ + public static String getMd5(String fileName) { + try { + File file = new File(fileName); + FileInputStream fis = new FileInputStream(file); + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] buffer = new byte[1024]; + int length = -1; + while ((length = fis.read(buffer, 0, 1024)) != -1) { + md.update(buffer, 0, length); + } + BigInteger bigInt = new BigInteger(1, md.digest()); + // System.out.println("文件md5值:" + bigInt.toString(16)); + return bigInt.toString(16); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static String getSHA256(String fileName) { + try { + File file = new File(fileName); + FileInputStream fis = new FileInputStream(file); + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] buffer = new byte[1024]; + int length = -1; + while ((length = fis.read(buffer, 0, 1024)) != -1) { + md.update(buffer, 0, length); + } + BigInteger bigInt = new BigInteger(1, md.digest()); + // System.out.println("文件SHA256值:" + bigInt.toString(16)); + return bigInt.toString(16); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/group24/1525619747/homework_20170328/src/testcase/FileDownloaderTest.java b/group24/1525619747/homework_20170328/src/testcase/FileDownloaderTest.java new file mode 100644 index 0000000000..44d392729e --- /dev/null +++ b/group24/1525619747/homework_20170328/src/testcase/FileDownloaderTest.java @@ -0,0 +1,78 @@ +package testcase; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.FileDownloader; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; +import com.coderising.helper.Tool; + +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://windows.php.net/downloads/releases/php-7.0.17-nts-Win32-VC14-x86.zip"; + String uriSHA256 = "d5f559fe2143b408ccb743dbd7af4406ebe4cdd7c2bec5f417a48dd89aa331b0"; + + String savePathDir = "D:/App_data/java/"; + String fileName = "php-7.0.17-nts-Win32-VC14-x86.zip"; + String downloadFileName = "D:/App_data/java/php-7.0.17-nts-Win32-VC14-x86.zip"; + + FileDownloader downloader = new FileDownloader(url, savePathDir, + fileName); + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + public void notifyFinished() { + downloadFinished = true; + } + }); + + downloader.execute(); + + while (!downloader.isFinished()) { + try { + System.out.println("还没有下载完成,休眠五秒"); + // 休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + // // 等待多线程下载程序执行完毕 + // while (!downloadFinished) { + // try { + // System.out.println("还没有下载完成,休眠五秒"); + // //休眠5秒 + // Thread.sleep(5000); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // } + System.out.println("下载完成!"); + + System.out.println(uriSHA256); + System.out.println(Tool.getSHA256(downloadFileName)); + assertEquals(uriSHA256, Tool.getSHA256(downloadFileName)); + + } + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/DownloadThread.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/DownloadThread.java new file mode 100644 index 0000000000..e3dc19e8da --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/DownloadThread.java @@ -0,0 +1,40 @@ +package com.johnChnia.coderising2017.download; + +import com.johnChnia.coderising2017.download.api.Connection; + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +public class DownloadThread extends Thread { + Connection conn; + int startPos; + int endPos; + CyclicBarrier barrier; + String localFile; + + public DownloadThread(Connection conn, int startPos, int endPos, String localFile, CyclicBarrier barrier) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + + public void run() { + try { + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + byte[] data = conn.read(startPos, endPos); + System.out.println("创建一个随机读取文件的对象"); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + file.seek(startPos); + System.out.println("要写数据了"); + file.write(data); + file.close(); + conn.close(); + System.out.println(this.currentThread().getName() + "once over"); + barrier.await(); + } catch (Exception e) { + // TODO: handle exception + } + } +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/FileDownloader.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/FileDownloader.java new file mode 100644 index 0000000000..02a0911bdd --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/FileDownloader.java @@ -0,0 +1,123 @@ +package com.johnChnia.coderising2017.download; + +import com.johnChnia.coderising2017.download.api.Connection; +import com.johnChnia.coderising2017.download.api.ConnectionManager; +import com.johnChnia.coderising2017.download.api.DownloadListener; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + + +public class FileDownloader { + private String url; + private String localFile = "YNote.exe"; + DownloadListener listener; + ConnectionManager cm; + + private static final int DOWNLOAD_THREAD_NUM = 3; + + public FileDownloader(String _url) { + 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(DOWNLOAD_THREAD_NUM, new Runnable() {// 当所有的Thread都调用 await方法时,会执行后面的 barrierAction,调用后面这个线程 + @Override + public void run() { + listener.notifyFinished(); + } + }); + + Connection conn = null; + try { + conn = cm.open(this.url); + int length = conn.getContentLength();// 拿到将要下载文件的长度 + createPlaceHolderFile(this.localFile, length);//占位 + System.out.println("占位完毕"); + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length);// 给每个线程分配开始位置和结束位置 + // 开始下载文件 + System.out.println("开始下载文件"); + for (int i = 0; i < DOWNLOAD_THREAD_NUM; i++) { + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + thread.start(); + System.out.println("第" + (i + 1) + "个线程已经启动"); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + System.out.println("即将关闭连接"); + if (conn != null) { + conn.close(); + System.out.println("关闭连接成功"); + } + } + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return this.listener; + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + RandomAccessFile file = new RandomAccessFile(fileName, "rw"); + file.setLength(contentLen); +// for (int i = 0; i < contentLen; i++) { +// file.write(0); +// } + file.close(); + } + + /** + * 给出线程数和文件长度,返回一个二维数组,里面存的是每个线程下载的开始位置和结束位置 + * + * @param threadNum + * @param contentLen + * @return + */ + private int[][] allocateDownloadRange(int threadNum, int contentLen) { + int[][] ranges = new int[threadNum][2];// 用二维数组存下每个线程的开始位置和结束位置 + + int eachThreadSize = contentLen / threadNum;// 每个线程需要下载的文件大小 + int left = contentLen % threadNum;// 剩下的归最后一个线程来处理 + + for (int i = 0; i < threadNum; i++) { + int startPos = i * eachThreadSize; + int endPos = (i + 1) * eachThreadSize - 1; + if ((i == (threadNum - 1))) { + endPos += left; + } + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + + return ranges; + } + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/FileDownloaderTest.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/FileDownloaderTest.java new file mode 100644 index 0000000000..a831a51a3f --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/FileDownloaderTest.java @@ -0,0 +1,61 @@ +package com.johnChnia.coderising2017.download; + +import com.johnChnia.coderising2017.download.api.ConnectionManager; +import com.johnChnia.coderising2017.download.api.DownloadListener; +import com.johnChnia.coderising2017.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.FileNotFoundException; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() throws FileNotFoundException { + + String url = "http://download.ydstatic.com/notewebsite/downloads/YNote.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/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/Connection.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/Connection.java new file mode 100644 index 0000000000..9913d25a7f --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/Connection.java @@ -0,0 +1,27 @@ +package com.johnChnia.coderising2017.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/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/ConnectionException.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/ConnectionException.java new file mode 100644 index 0000000000..87c2121d4e --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.johnChnia.coderising2017.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/ConnectionManager.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/ConnectionManager.java new file mode 100644 index 0000000000..0b904d1d7a --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.johnChnia.coderising2017.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/DownloadListener.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/DownloadListener.java new file mode 100644 index 0000000000..6aa10e3bcc --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.johnChnia.coderising2017.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/impl/ConnectionImpl.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..5d0095c5de --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/impl/ConnectionImpl.java @@ -0,0 +1,71 @@ +package com.johnChnia.coderising2017.download.impl; + +import com.johnChnia.coderising2017.download.api.Connection; +import com.johnChnia.coderising2017.download.api.ConnectionException; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; + +public class ConnectionImpl implements Connection { + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException { + try { + url = new URL(_url); + } catch (Exception e) { + throw new ConnectionException(); + } + } + @Override + public byte[] read(int startPos, int endPos) throws IOException { + //开始 + System.out.println("开始"); + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + // 设置读取的位置 + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + // 从URL连接获得输入流 + 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 (Exception e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + } +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/impl/ConnectionManagerImpl.java b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..2c3a0cc520 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coderising2017/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.johnChnia.coderising2017.download.impl; + +import com.johnChnia.coderising2017.download.api.Connection; +import com.johnChnia.coderising2017.download.api.ConnectionException; +import com.johnChnia.coderising2017.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java index a91f03573a..01ba928128 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java @@ -20,6 +20,7 @@ public LinkedList() { } + private static class Node { T element; Node next; @@ -75,6 +76,15 @@ public void addFirst(E element) { size++; } + /** + * Appends the specified element to the end of this list. + * + * @param element element to be appended to this list. + */ + public void addLast(E element) { + add(element); + } + /** * Inserts the specified element at the specified position in this list. @@ -115,20 +125,27 @@ public void add(int index, E element) { * * @throws RuntimeException if the list is empty. */ - public void remove() { + public E removeLast() { if (size == 0) throw new RuntimeException("linkList size should greater than or equal to 1"); + E element; Node next = first.next; if (next == null) { + element = first.element; + first = null; } else { Node last = first; while (last.next != null) last = last.next; last.prev.next = null; + + element = last.element; + last = null; // help GC } size--; + return element; } @@ -163,6 +180,7 @@ public E removeFirst() { return element; } + /** * Returns the element at the specified position in this list. * @@ -229,6 +247,232 @@ public String toString() { return sb.toString(); } + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + Node next; + Node current = first; + for (int i = 0; i < size; i++) { + next = current.next; + current.next = current.prev; + current.prev = next; + if (next != null) { + current = next; + } + } + first = current; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + int index = size() / 2; + Node current = first; + Node prev; + for (int i = 0; i < index; i++) { + prev = current; + current = current.next; + delete(prev); + } + current.prev = null; + first = current; + size = size - index; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + checkElementIndex(i); + if (length + i > size()) { + throw new IllegalArgumentException("Length + i should less than or equal " + size()); + } + Node head = first; + Node tail = first; + if (i == 0 && length == size()) { + first = null; + } else if (i == 0 && length < size()) { + for (int j = 0; j < length; j++) { + head = head.next; + } + head.prev = null; + first = head; + } else { + for (int j = 0; j < i; j++) { + head = head.next; + } + head = head.prev; + for (int j = 0; j < length + i; j++) { + tail = tail.next; + } + head.next = tail; + if (tail != null) { + tail.prev = head; + } + } + size = size - length; + } + + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public int[] getElements(LinkedList list) { + int[] newArray = new int[list.size()]; + Node mapNode = list.first; + Node valueNode = this.first; + int indexOfList = 0; + int indexOfArray = 0; + while (mapNode != null && valueNode != null) { + int mapValue = (int) mapNode.element; + if (mapValue == indexOfList) { + newArray[indexOfArray] = (int) valueNode.element; + mapNode = mapNode.next; + valueNode = valueNode.next; + indexOfArray++; + } else { + mapNode = mapNode.next; + } + indexOfList++; + } + return newArray; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + Node pNode = first; + Node qNode = list.first; + Node prev = null; + Node deletedNode; + while (pNode != null && qNode != null) { + if ((int) qNode.element < (int) pNode.element) { + qNode = qNode.next; + } else if ((int) qNode.element > (int) pNode.element) { + prev = pNode; + pNode = pNode.next; + } else { + if (prev == null) { // 头结点 + first = pNode.next; + } else { + prev.next = pNode.next; + } + deletedNode = pNode; + pNode = pNode.next; + qNode = qNode.next; + delete(deletedNode); + size--; + } + } + + } + + private void delete(Node node) { + node.element = null; + node.prev = null; + node.next = null; + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + Node current = first; + Node next = current.next; + while (next != null) { + if (current.element == next.element) { + current.next = next.next; + if (next.next != null) { + next.next.prev = current; + } + delete(next); + next = current.next; + size--; + } else { + current = current.next; + next = next.next; + } + + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + Node current = first; + Node prev = null; + Node deletedNode; + while (current != null) { + if ((int) current.element >= max) { + break; + } + if ((int) current.element > min && (int) current.element < max) { + if (prev == null) { // 头结点 + first = current.next; + } else { + prev.next = current.next; + } + deletedNode = current; + current = current.next; + delete(deletedNode); // help gc + size--; + } else { + prev = current; + current = current.next; + } + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + LinkedList l = new LinkedList(); + Node pNode = first; + Node qNode = list.first; + while (pNode != null && qNode != null) { + if ((int) pNode.element < (int) qNode.element) { + pNode = pNode.next; + } else if ((int) pNode.element > (int) qNode.element) { + qNode = qNode.next; + } else { + l.add(pNode.element); + pNode = pNode.next; + qNode = qNode.next; + } + } + return l; + } + + /** * Constructs an IndexOutOfBoundsException detail message. * Of the many possible refactorings of the error handling code, diff --git a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/LinkedListTest.java b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/LinkedListTest.java index d09362cdf9..9a72c0d54a 100644 --- a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/LinkedListTest.java +++ b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/LinkedListTest.java @@ -3,6 +3,9 @@ import org.junit.Before; import org.junit.Test; +import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -17,6 +20,18 @@ public class LinkedListTest { private LinkedList linkList4; private LinkedList linkList5; private LinkedList linkList6; + private LinkedList linkList7; + private LinkedList linkList8; + private LinkedList linkList9; + private LinkedList linkList10; + private LinkedList linkList11; + private LinkedList linkList12; + private LinkedList linkList13; + private LinkedList linkList14; + private LinkedList linkList15; + private LinkedList linkList16; + private LinkedList linkList17; + private LinkedList linkList18; @Before public void setUp() throws Exception { @@ -26,6 +41,18 @@ public void setUp() throws Exception { linkList4 = new LinkedList<>(); linkList5 = new LinkedList<>(); linkList6 = new LinkedList<>(); + linkList7 = new LinkedList<>(); + linkList8 = new LinkedList<>(); + linkList9 = new LinkedList<>(); + linkList10 = new LinkedList<>(); + linkList11 = new LinkedList<>(); + linkList12 = new LinkedList<>(); + linkList13 = new LinkedList<>(); + linkList14 = new LinkedList<>(); + linkList15 = new LinkedList<>(); + linkList16 = new LinkedList<>(); + linkList17 = new LinkedList<>(); + linkList18 = new LinkedList<>(); } @Test @@ -56,12 +83,12 @@ public void testAddFirst() { } @Test - public void testRemove() { + public void testRemoveLast() { for (int i = 0; i < 2; i++) { linkList4.addFirst(i); } - linkList4.remove(); - linkList4.remove(); + linkList4.removeLast(); + linkList4.removeLast(); assertThat(linkList4.size(), equalTo(0)); } @@ -88,4 +115,103 @@ public void testRemoveFirst() { assertThat(linkList6.get(0), equalTo(0)); } + @Test + public void testReverse() { + linkList7.add(3); + linkList7.add(7); + linkList7.add(10); + linkList7.reverse(); + assertThat(linkList7.toString(), containsString("10→7→3")); + } + + @Test + public void testRemoveFirstHalf() { + linkList8.add(2); + linkList8.add(5); + linkList8.add(7); + linkList8.add(8); + linkList8.add(10); + linkList8.removeFirstHalf(); + assertThat(linkList8.toString(), containsString("7→8→10")); + } + + @Test + public void testRemove() { + for (int i = 1; i < 6; i++) { + linkList9.add(i); + } + linkList9.remove(0, 4); + assertThat(linkList9.toString(), containsString("5")); + } + + @Test + public void testRemoveDuplicateValues() { + linkList11.add(1); + linkList11.add(1); + linkList11.add(1); + linkList11.add(2); + linkList11.add(3); + linkList11.add(3); + linkList11.removeDuplicateValues(); + assertThat(linkList11.toString(), containsString("1→2→3")); + } + + @Test + public void testRemoveRange() { + linkList10.add(1); + linkList10.add(1); + linkList10.add(2); + linkList10.add(3); + linkList10.add(4); + linkList10.add(5); + linkList10.add(6); + linkList10.removeRange(1, 4); + assertThat(linkList10.toString(), containsString("4→5→6")); + } + + @Test + public void testIntersection() { + for (int i = 1; i < 6; i++) { + linkList12.add(i); + } + for (int i = 3; i < 9; i++) { + linkList13.add(i); + } + assertThat(linkList12.intersection(linkList13).toString() + , containsString("3→4→5")); + } + + @Test + public void testGetElements() { + linkList15.add(1); + linkList15.add(3); + linkList15.add(4); + linkList15.add(6); + linkList14.add(11); + linkList14.add(101); + linkList14.add(201); + linkList14.add(301); + linkList14.add(401); + linkList14.add(501); + linkList14.add(601); + linkList14.add(701); + linkList14.getElements(linkList15); + assertThat(Arrays.toString(linkList14.getElements(linkList15)) + , containsString("[101, 301, 401, 601]")); + } + + @Test + public void testSubtract() { + for (int i = 1; i < 5; i++) { + linkList17.add(i); + } + for (int i = 1; i < 4; i++) { + linkList18.add(i); + } + linkList17.subtract(linkList18); + assertThat(linkList17.toString() + , containsString("4")); + + } + } \ No newline at end of file diff --git a/group24/330657387/.classpath b/group24/330657387/.classpath index 3e0fb272a8..80c86612f0 100644 --- a/group24/330657387/.classpath +++ b/group24/330657387/.classpath @@ -3,5 +3,6 @@ + diff --git a/group24/330657387/src/main/week02/litestruts/CustomException.java b/group24/330657387/src/main/week02/litestruts/CustomException.java new file mode 100644 index 0000000000..e1de4648d7 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/CustomException.java @@ -0,0 +1,21 @@ +package main.week02.litestruts; + +import java.io.IOException; + +import org.jdom2.JDOMException; + +public class CustomException extends RuntimeException { + + public CustomException(IOException e) { + super(e.getMessage()); + } + + public CustomException(JDOMException e) { + super(e.getMessage()); + } + + public CustomException(String msg) { + super(msg); + } + +} diff --git a/group24/330657387/src/main/week02/litestruts/LoginAction.java b/group24/330657387/src/main/week02/litestruts/LoginAction.java new file mode 100644 index 0000000000..300c29e4d2 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package main.week02.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/group24/330657387/src/main/week02/litestruts/Struts.java b/group24/330657387/src/main/week02/litestruts/Struts.java new file mode 100644 index 0000000000..07ecadddec --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/Struts.java @@ -0,0 +1,79 @@ +package main.week02.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class Struts { + + public static View runAction(String actionName, + Map parameters) throws Exception, + NoSuchFieldException { + + /* + * + * 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字段中。 + */ + + XmlSaxUtil config = new XmlSaxUtil("struts.xml"); + String classname = config.getClassName(actionName); + // 1 通过反射存入parameter + // 没有这个类名就报错 + if (null == classname) { + throw new CustomException("没有这个action啊!"); + } + // 通过反射获取实例 + Class controllerClass = Class.forName(classname); + // 创建实例 + Object controller = controllerClass.newInstance(); + // 获取类中声明的全部成员变量 + Field[] fields = controllerClass.getDeclaredFields(); + // 备用 + Method m; + // 得到该action所有result的结果合集 + + // 为controller注入变量 + for (String key : parameters.keySet()) { + for (Field f : fields) { + if (f.getName() == key) { + m = controllerClass.getMethod("set" + + key.replace(key.substring(0, 1),key.substring(0, 1).toUpperCase()), String.class); + m.invoke(controller, parameters.get(key)); + break; + } + } + } + + // 2 通过反射调用excute 获取返回值 + m = controllerClass.getMethod("execute"); + String result = (String) m.invoke(controller); + + // 3 把message放到View对象的parameters + View view = new View(); + Map viewParam = new HashMap(); + + // 新建并传入View的viewParam属性值 + m = controllerClass.getMethod("getMessage"); + viewParam.put("message", (String) m.invoke(controller)); + view.setParameters(viewParam); + + // 传入jsp路径 + view.setJsp(config.getResultView(actionName, result)); + + return view; + } + +} diff --git a/group24/330657387/src/main/week02/litestruts/StrutsTest.java b/group24/330657387/src/main/week02/litestruts/StrutsTest.java new file mode 100644 index 0000000000..1cc90265f7 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/StrutsTest.java @@ -0,0 +1,39 @@ +package main.week02.litestruts; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() throws Exception { + + 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 Exception { + 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/group24/330657387/src/main/week02/litestruts/View.java b/group24/330657387/src/main/week02/litestruts/View.java new file mode 100644 index 0000000000..c333d79d25 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/View.java @@ -0,0 +1,23 @@ +package main.week02.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/group24/330657387/src/main/week02/litestruts/XmlDomUtil.java b/group24/330657387/src/main/week02/litestruts/XmlDomUtil.java new file mode 100644 index 0000000000..d02319bc18 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/XmlDomUtil.java @@ -0,0 +1,24 @@ +package main.week02.litestruts; + +public class XmlDomUtil { + /*// 0 读取xml文档的元素值 + // 获取工厂 + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + // 产生解析器 + DocumentBuilder builder = factory.newDocumentBuilder(); + // 解析xml文档,得到代表文档的document对象 + Document document = builder.parse(new File( + "./src/main/week02/litestruts/struts.xml")); + // 根据标签名获取节点列表 + NodeList actionList = document.getElementsByTagName("action");*/ + + /* HashMap actionMap = new HashMap();*/ + + /*for (int i = 0; i < actionList.getLength(); i++) { + // 获取节点列表里的节点 + Element action = (Element) actionList.item(i); + // 获取节点的属性值 + actionMap.put(action.getAttribute("name"), + action.getAttribute("class")); + }*/ +} diff --git a/group24/330657387/src/main/week02/litestruts/XmlSaxUtil.java b/group24/330657387/src/main/week02/litestruts/XmlSaxUtil.java new file mode 100644 index 0000000000..78f117a5f1 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/XmlSaxUtil.java @@ -0,0 +1,115 @@ +package main.week02.litestruts; + +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 XmlSaxUtil { + + Map actions = new HashMap<>(); + + public XmlSaxUtil(String fileName) { + // 得到包名 + String packageName = this.getClass().getPackage().getName(); + // 把包名转化成路径的一部分 + packageName = packageName.replace('.', '/'); + // 基于流的sax方式解析,需要先给出流,从类的同地址下找文件。 + InputStream is = this.getClass().getResourceAsStream( + "/" + packageName + "/" + fileName); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + throw new CustomException(e); + } + } + + private void parseXML(InputStream is) { + // 解析器工厂 + SAXBuilder builder = new SAXBuilder(); + + try { + // 获取xml文件对象 + 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 CustomException(e); + + } catch (IOException e) { + throw new CustomException(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/group24/330657387/src/main/week02/litestruts/struts.xml b/group24/330657387/src/main/week02/litestruts/struts.xml new file mode 100644 index 0000000000..2bbb2f3620 --- /dev/null +++ b/group24/330657387/src/main/week02/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/group24/330657387/src/main/week02/practice/ArrayUtil.java b/group24/330657387/src/main/week02/practice/ArrayUtil.java index 3ab82a31e8..d174fdbe27 100644 --- a/group24/330657387/src/main/week02/practice/ArrayUtil.java +++ b/group24/330657387/src/main/week02/practice/ArrayUtil.java @@ -1,5 +1,10 @@ package main.week02.practice; +import java.util.ArrayList; +import java.util.Iterator; + +import com.sun.xml.internal.ws.org.objectweb.asm.Label; + public class ArrayUtil { /** @@ -40,7 +45,7 @@ public int[] removeZero(int[] oldArray) { } } int[] newArray = new int[i]; - System.arraycopy(oldArray, 0, newArray, 0,newArray.length); + System.arraycopy(oldArray, 0, newArray, 0, newArray.length); return newArray; } @@ -54,7 +59,56 @@ public int[] removeZero(int[] oldArray) { */ public int[] merge(int[] array1, int[] array2) { - return null; + if (array1.length == 0) { + return array2; + } + if (array2.length == 0) { + return array1; + } + int n = 0; + int[] merge = new int[array1.length + array2.length]; + int i = 0, j = 0; + while (i < array1.length || j < array2.length) { + if (array1[i] == array2[j]) { + merge[n] = array1[i]; + n++; + i++; + j++; + if (i == array1.length) { + System.arraycopy(array2, j, merge, n, array2.length - j); + n += array2.length - j; + break; + } + if (j == array2.length) { + System.arraycopy(array1, i, merge, n, array1.length - i); + n += array1.length - i; + break; + } + continue; + } + if (array1[i] < array2[j]) { + merge[n] = array1[i]; + n++; + i++; + if (i == array1.length) { + System.arraycopy(array2, j, merge, n, array2.length - j); + n += array2.length - j; + break; + } + } else { + merge[n] = array2[j]; + n++; + j++; + if (j == array2.length) { + System.arraycopy(array1, i, merge, n, array1.length - i); + n += array1.length - i; + break; + } + } + } + int[] res = new int[n]; + System.arraycopy(merge, 0, res, 0, n); + return res; } /** @@ -67,7 +121,9 @@ public int[] merge(int[] array1, int[] array2) { * @return */ public int[] grow(int[] oldArray, int size) { - return null; + int[] res = new int[oldArray.length + size]; + System.arraycopy(oldArray, 0, res, 0, oldArray.length); + return res; } /** @@ -78,7 +134,24 @@ public int[] grow(int[] oldArray, int size) { * @return */ public int[] fibonacci(int max) { - return null; + if (max <= 1) { + return new int[0]; + } + ArrayList list = new ArrayList(); + list.add(1); + list.add(1); + int index = 1; + while (list.get(index) + list.get(index - 1) < max) { + list.add(list.get(index) + list.get(index - 1)); + index++; + } + Iterator iter = list.iterator(); + int[] res = new int[list.size()]; + int i = 0; + while (iter.hasNext()) { + res[i++] = iter.next(); + } + return res; } /** @@ -88,7 +161,22 @@ public int[] fibonacci(int max) { * @return */ public int[] getPrimes(int max) { - return null; + if (max <= 2) { + return new int[0]; + } + int n = 2; + int arr[] = new int[max]; + int j = 0; + a: for (; n < max; n++) { + for (int i = 2; i < n / 2 + 1; i++) { + if (n % i == 0) + continue a; + } + arr[j++] = n; + } + int[] res = new int[j]; + System.arraycopy(arr, 0, res, 0, j); + return res; } /** @@ -98,7 +186,23 @@ public int[] getPrimes(int max) { * @return */ public int[] getPerfectNumbers(int max) { - return null; + if (max <= 6) { + return new int[0]; + } + int n = 6, sum = 0, j = 0; + int[] arr = new int[max]; + for (; n < max; n++, sum = 0) { + for (int i = 1; i < n / 2 + 1; i++) { + if (n % i == 0) + sum += i; + + } + if (sum == n) + arr[j++] = n; + } + int[] res = new int[j]; + System.arraycopy(arr, 0, res, 0, j); + return res; } /** @@ -109,7 +213,17 @@ public int[] getPerfectNumbers(int max) { * @return */ public String join(int[] array, String seperator) { - return null; + if (array.length == 0) { + return ""; + } + StringBuilder sb = new StringBuilder(); + int i; + for (i = 0; i < array.length - 1; i++) { + sb.append(array[i]); + sb.append(seperator); + } + sb.append(array[i]); + return sb.toString(); } } diff --git a/group24/330657387/src/test/week02/practice/ArrayUtilTest.java b/group24/330657387/src/test/week02/practice/ArrayUtilTest.java index 1bf97fced3..0e29853068 100644 --- a/group24/330657387/src/test/week02/practice/ArrayUtilTest.java +++ b/group24/330657387/src/test/week02/practice/ArrayUtilTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.*; import java.util.Arrays; +import java.util.HashMap; import main.week02.practice.ArrayUtil; @@ -48,32 +49,63 @@ public void testRemoveZero() { @Test public void testMerge() { - fail("Not yet implemented"); + int[][] array1 = {{0,1,2,5,6,9,11}, + {1,2,3}, + {}}; + int[][] array2 = {{0,3,8,15,16,20,50},{1},{}}; + for(int i=0;i<3;i++){ + System.out.println("前:"+Arrays.toString(array1[i])+Arrays.toString(array2[i])); + System.out.println("后:"+Arrays.toString(util.merge(array1[i], array2[i]))); + } } @Test public void testGrow() { - fail("Not yet implemented"); + int[][] origin = {{1,20,3,65,4,6,9,7}, + {}, + {1,0}, + {1,0,2,3}, + {23,0,0,32}}; + for(int[] a : origin){ + System.out.println("前:"+Arrays.toString(a)); + System.out.println("后:"+Arrays.toString(util.grow(a, 3))); + } } @Test public void testFibonacci() { - fail("Not yet implemented"); + int[] origin = {1,2,3,65,4,6,9,7}; + for(int a : origin){ + System.out.println(Arrays.toString(util.fibonacci(a))); + } } @Test public void testGetPrimes() { - fail("Not yet implemented"); + int[] origin = {1,2,3,65,4,6,9,7}; + for(int a : origin){ + System.out.println(Arrays.toString(util.getPrimes(a))); + } } @Test public void testGetPerfectNumbers() { - fail("Not yet implemented"); + int[] origin = {1,2,3,65,4,6,999,7}; + for(int a : origin){ + System.out.println(Arrays.toString(util.getPerfectNumbers(a))); + } } @Test public void testJoin() { - fail("Not yet implemented"); + int[][] origin = {{1,20,3,65,4,6,9,7}, + {}, + {1,0}, + {1,0,2,3}, + {23,0,0,32}}; + for(int[] a : origin){ + System.out.println(util.join(a , "=")); + } } } diff --git "a/group24/330657387/\345\215\232\345\256\242\345\234\260\345\235\200.txt" "b/group24/330657387/\345\215\232\345\256\242\345\234\260\345\235\200.txt" new file mode 100644 index 0000000000..76ae770288 --- /dev/null +++ "b/group24/330657387/\345\215\232\345\256\242\345\234\260\345\235\200.txt" @@ -0,0 +1,10 @@ +һܲhttp://www.cnblogs.com/sargeles/p/6605493.html +ڶܲhttp://www.cnblogs.com/sargeles/p/6605945.html +ܲ +ܲ +ܲ +ܲ +ܲ +ڰܲ +ھܲ +ʮܲ diff --git a/group24/448641125/src/com/donaldy/basic/LRUPageFrame.java b/group24/448641125/src/com/donaldy/basic/LRUPageFrame.java new file mode 100644 index 0000000000..9ed6d7945e --- /dev/null +++ b/group24/448641125/src/com/donaldy/basic/LRUPageFrame.java @@ -0,0 +1,133 @@ +package com.donaldy.basic; + +/** + * 用双向链表实现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 Node first;// 链表头 + private Node last;// 链表尾 + + private int spareNum = 3; + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + + /** + * 1.找到, + * 则将此元素提到队首 + * 2.找不到,则new一个,并加在队首 + * 1.队伍是满,则踢掉队尾 + * 2.队伍不满,则添加在队首 + */ + Node node = first; + + while (node != null) { + + if (pageNum == node.pageNum) { + + if (node == first) + return; + + if (node == last) { + final Node prevNode = node.prev; + prevNode.next = null; + last = prevNode; + node.prev = null; + node.next = first; + first.prev = node; + first = node; + + return ; + } + + final Node prevNode = node.prev; + final Node nextNode = node.next; + prevNode.next = nextNode; + nextNode.prev = prevNode; + + node.prev = null; + node.next = first; + first = node; + + return; + } + + node = node.next; + } + + Node newNode = new Node(pageNum); + + if (spareNum == 0) { + final Node f = first; + final Node l = last; + + f.prev = newNode; + newNode.next = f; + first = newNode; + + last = l.prev; + last.next = null; + l.prev = null; + + return ; + } + + if (spareNum == capacity) { + first = newNode; + last = newNode; + spareNum --; + return; + } + + first.prev = newNode; + newNode.next = first; + first = newNode; + spareNum --; + } + + + + 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/group24/448641125/src/com/donaldy/basic/LRUPageFrameTest.java b/group24/448641125/src/com/donaldy/basic/LRUPageFrameTest.java new file mode 100644 index 0000000000..4d4d8f4f7e --- /dev/null +++ b/group24/448641125/src/com/donaldy/basic/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.donaldy.basic; + +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/group24/448641125/src/com/donaldy/download/DownloadThread.java b/group24/448641125/src/com/donaldy/download/DownloadThread.java index 2d018cec3d..cdb24fcece 100644 --- a/group24/448641125/src/com/donaldy/download/DownloadThread.java +++ b/group24/448641125/src/com/donaldy/download/DownloadThread.java @@ -30,12 +30,11 @@ public void run(){ byte [] buffer = conn.read(startPos, endPos); - int hasRead = conn.getContentLength(); + int hasRead = buffer.length; System.out.println("hasRead : " + hasRead); - if (hasRead > 0) - raf.write(buffer, 0, hasRead); + raf.write(buffer, 0, hasRead); } catch (IOException e) { e.printStackTrace(); diff --git a/group24/448641125/src/com/donaldy/download/FileDownloader.java b/group24/448641125/src/com/donaldy/download/FileDownloader.java index 811d462be4..52745aae2c 100644 --- a/group24/448641125/src/com/donaldy/download/FileDownloader.java +++ b/group24/448641125/src/com/donaldy/download/FileDownloader.java @@ -47,19 +47,20 @@ public void execute() throws IOException { int length = conn.getContentLength(); - int partLength = length ; + System.out.println("length : " + length); + + int partLength = length / 3 + 1; System.out.println("partLengh : " + partLength); int startPos = 0; - /*for (int i = 0 ; i < 5; ++ i) { - System.out.println("Thread is ready..."); + for (int i = 0 ; i < 3; ++ i) { + System.out.println("Thread:" + i + " is ready..."); executorService.execute(new DownloadThread(conn, startPos, startPos + partLength)); + System.out.println("startPos: " + startPos + ", endPos: " + (startPos + partLength)); startPos += partLength; - }*/ - - new DownloadThread(conn, startPos, startPos + partLength).start(); + } executorService.shutdown(); diff --git a/group24/448641125/src/com/donaldy/download/impl/ConnectionImpl.java b/group24/448641125/src/com/donaldy/download/impl/ConnectionImpl.java index 589a010e68..7d24952b20 100644 --- a/group24/448641125/src/com/donaldy/download/impl/ConnectionImpl.java +++ b/group24/448641125/src/com/donaldy/download/impl/ConnectionImpl.java @@ -1,7 +1,9 @@ package com.donaldy.download.impl; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import com.donaldy.download.api.Connection; @@ -25,25 +27,29 @@ public byte[] read(int startPos, int endPos) throws IOException { if (inputStream == null) return null; - System.out.println("inputStream is not equal null"); - inputStream.skip(startPos); - int length = endPos - startPos + 1; - - System.out.println("要读的长度 : " + length); + int totalLen = endPos - startPos + 1; - byte [] buffer = new byte[length]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - System.out.println("buffer - 1: " + buffer.length); + byte [] buffer = new byte[1024]; - contentLength = inputStream.read(buffer); + while (baos.size() < totalLen) { + int len = inputStream.read(buffer); + if (len < 0) + break; + baos.write(buffer, 0, len); + } - System.out.println("buffer - 2: " + buffer.length); + if (baos.size() > totalLen) { + byte [] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } - System.out.println("contentLength : " + contentLength); + System.out.println("读入:" + totalLen); - return buffer; + return baos.toByteArray(); } @Override diff --git a/group24/448641125/src/com/donaldy/download/impl/ConnectionManagerImpl.java b/group24/448641125/src/com/donaldy/download/impl/ConnectionManagerImpl.java index 9c98b0d4fb..04fbf876df 100644 --- a/group24/448641125/src/com/donaldy/download/impl/ConnectionManagerImpl.java +++ b/group24/448641125/src/com/donaldy/download/impl/ConnectionManagerImpl.java @@ -6,8 +6,7 @@ import java.io.IOException; import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.ProtocolException; + import java.net.URL; public class ConnectionManagerImpl implements ConnectionManager { @@ -40,8 +39,6 @@ public Connection open(String url) throws ConnectionException { conn.setContentLength(connection.getContentLength()); - System.out.println("connection.getContentLength() : " + connection.getContentLength()); - conn.setInputStream(connection.getInputStream()); return conn; diff --git a/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java b/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..c4a64b26d6 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java @@ -0,0 +1,80 @@ +package com.donaldy.jvm.loader; + +import java.io.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + static final int BUFFER_SIZE = 1024; + + public byte[] readBinaryCode(String className) { + + + + for (String clzPath : clzPaths) { + + File file = new File(clzPath + className.replace(".", "\\") + ".class"); + + + if (!file.exists()) + continue; + + try ( + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + ByteArrayOutputStream bos = new ByteArrayOutputStream() + ) + { + + byte [] buffer = new byte[BUFFER_SIZE]; + + int len; + + while ((len = bis.read(buffer, 0, BUFFER_SIZE)) > 0) { + bos.write(buffer, 0, len); + } + + return bos.toByteArray(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return null; + + } + + + public void addClassPath(String path) { + if (path == null) + return; + + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + int length = clzPaths.size(); + for (int i = 0 ; i < length; ++i) { + sb.append(clzPaths.get(i)); + if (i + 1 < length) + sb.append(";"); + } + return sb.toString(); + } + + + + + +} diff --git a/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java b/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..2ed50aa8b5 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,92 @@ +package com.donaldy.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.donaldy.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + static String path1 = "D:\\tools\\Code\\Y_Repository\\coding2017\\group24\\448641125\\out\\production\\448641125\\"; + 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.donaldy.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1050, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.donaldy.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 getContentLength()) { + throw new IndexOutOfBoundsException(); + } + if (startPos >= endPos) { + throw new IllegalArgumentException(); + } + byte[] bytes = new byte[endPos - startPos + 1]; + + InputStream inputStream = httpURLConnection.getInputStream(); + BufferedInputStream bis = new BufferedInputStream(inputStream); + bis.read(bytes, startPos ,bytes.length-1); + return bytes; + } + + + @Override + public int getContentLength() { + return httpURLConnection.getContentLength(); + } + + @Override + public void close() { + httpURLConnection.disconnect(); + } + + @Override + public InputStream getInputStream() throws IOException { + return httpURLConnection.getInputStream(); + } + +} diff --git a/group24/494800949/src/main/java/com/coding/week3/download/impl/ConnectionManagerImpl.java b/group24/494800949/src/main/java/com/coding/week3/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..3fd451036b --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week3/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,37 @@ +package com.coding.week3.download.impl; + + +import com.coding.week3.download.api.Connection; +import com.coding.week3.download.api.ConnectionException; +import com.coding.week3.download.api.ConnectionManager; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + try { + // 统一资源 + URL realurl = new URL(url); + // 连接类的父类,抽象类 + URLConnection urlConnection = realurl.openConnection(); + // http的连接类 + HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection; + // 设定请求的方法,默认是GET + httpURLConnection.setRequestMethod("GET"); + httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + // 设置字符编码 + httpURLConnection.setRequestProperty("Charset", "UTF-8"); + // 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。 + httpURLConnection.connect(); + return new ConnectionImpl(httpURLConnection); + } catch (java.io.IOException e) { + e.printStackTrace(); + throw new ConnectionException(e.getMessage()); + } + } + +} diff --git a/group24/494800949/src/test/java/com/coding/week3/FileDownloaderTest.java b/group24/494800949/src/test/java/com/coding/week3/FileDownloaderTest.java new file mode 100644 index 0000000000..5b423f145f --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week3/FileDownloaderTest.java @@ -0,0 +1,103 @@ +package com.coding.week3; + +import com.coding.week3.download.FileDownloader; +import com.coding.week3.download.api.ConnectionManager; +import com.coding.week3.download.api.DownloadListener; +import com.coding.week3.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.*; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + static final int DEFAULT_THREADS_NUM = 5; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() throws IOException { + +// String url = "http://101.95.48.97:8005/res/upload/interface/apptutorials/manualstypeico/6f83ce8f-0da5-49b3-bac8-fd5fc67d2725.png"; +// String url = "http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-arm32-vfp-hflt.tar.gz"; +// String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1490808670106&di=48aa6fb7af641f0cb6f9e19120b60c7c&imgtype=0&src=http%3A%2F%2Fwww.ntjoy.com%2Fliv_loadfile%2Fhealth%2Fdzcs%2Fnvr%2Ffold1%2F1360480639_97304600.jpg"; + String url = "https://download.jetbrains.com/idea/ideaIU-2017.1.exe"; + String path = new File("").getAbsolutePath(); + String filename = url.substring(url.lastIndexOf("/"), url.length()); + filename = path +File.separator + filename; + + FileDownloader downloader = new FileDownloader(DEFAULT_THREADS_NUM, filename, 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("下载完成!"); + + + + } + + + @Test + public void lenTest(){ + int lastLen = 0; + int length = 10232; + int nThread = 10; + int perLenOfThread = 0; + + if ( length % nThread == 0) + perLenOfThread = length / nThread; + else { + lastLen = length % nThread; + perLenOfThread = (length - lastLen) / nThread; + } + Assert.assertEquals(perLenOfThread, 1023); + Assert.assertEquals(lastLen, 2); + + Thread[] threads = new Thread[nThread+1]; + if ( length % nThread == 0) { + perLenOfThread = length / nThread; + } + else { + lastLen = length % nThread; + perLenOfThread = (length - lastLen) / nThread; + } + for (int i = 0; i <= nThread; i++) { + if ( i < nThread) { + System.out.println("startPos: " + perLenOfThread * i); + System.out.println("endPos: " + (perLenOfThread * (i + 1) - 1)); + } else { + System.out.println("startPos: " + perLenOfThread * nThread); + System.out.println("endPos: " + (length - 1)); + } + } + } +} diff --git a/group24/626451284/pom.xml b/group24/626451284/pom.xml index 534ff39232..507953adce 100644 --- a/group24/626451284/pom.xml +++ b/group24/626451284/pom.xml @@ -7,6 +7,4 @@ com.github.wdn coding2017 1.0-SNAPSHOT - - \ No newline at end of file diff --git a/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/array/ArrayUtil.java b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..76a6cb326e --- /dev/null +++ b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/array/ArrayUtil.java @@ -0,0 +1,230 @@ +package com.github.wdn.coding2017.coderising.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 void reverseArray(int[] origin) { + int length = origin.length; + for (int i = 0; i < length/2; i++) { + origin[i]=origin[i]+origin[length-1-i]; + origin[length-1-i] = origin[i]-origin[length-1-i]; + origin[i] = origin[i]-origin[length-1-i]; + } + } + /** + * 现在有如下的一个数组: 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){ + int[] result = new int[oldArray.length]; + int resultSize=0; + for (int i = 0; i < oldArray.length; i++) { + int item = oldArray[i]; + if (item!=0){ + result[resultSize]=item; + resultSize++; + } + } + if(resultSize=array1.length && array2Index>=array2.length){ + break; + } + int array1Value = array1Index < array1.length ? array1[array1Index] : array2[array2Index]; + int array2Value = array2Index < array2.length ? array2[array2Index] : array1[array1Index]; + if (array1Value > array2Value) { + mergeArr[i] = array2Value; + array2Index++; + } else if (array1Value < array2Value) { + mergeArr[i] = array1Value; + array1Index++; + }else{ + mergeArr[i] = array1Value; + array1Index++; + array2Index++; + } + mergeArrIndex++; + } + return Arrays.copyOfRange(mergeArr,0,mergeArrIndex); + */ + } + /** + * 把一个已经存满数据的数组 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){ + if (size<0 || oldArray.length+size>Integer.MAX_VALUE){ + throw new IndexOutOfBoundsException(); + } + + // 方法一:使用jdk自带方法 + //return Arrays.copyOf(oldArray,oldArray.length+size); + + // 方法二:遍历 + int[] growArr = new int[oldArray.length+size]; + for (int i = 0; i < oldArray.length; i++) { + growArr[i] = oldArray[i]; + } + return growArr; + } + + /** + * 斐波那契数列为: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){ + if(max<1 || max>Integer.MAX_VALUE){ + throw new IllegalArgumentException(); + } + int[] initArr = new int[]{1, 1}; + if(max<=2){ + return initArr; + } + int aIndex = 0; + int bIndex = 1; + int[] fibonacciArr = Arrays.copyOf(initArr,max); + int index = 2; + while(fibonacciArr[aIndex]+fibonacciArr[bIndex]> strutsMap = s.readStrutsXml(); + System.out.println(strutsMap); + } + public static View runAction(String actionName, Map parameters) { + Map> strutsMap = readStrutsXml(); + View view = new View(); + if(actionName.contains(actionName)){ + Map actionMap = strutsMap.get(actionName); + Map resultMap = (Map) actionMap.get("result"); + String actionClassName = actionMap.get("class").toString(); + System.out.println(actionClassName); + try { + Class c = Class.forName(actionClassName); + // 创建实例 + Object instance = c.newInstance(); + // 根据parameters调用setter方法 + for(Map.Entry entry:parameters.entrySet()){ + String key = entry.getKey(); + String value = entry.getValue(); + Method setter = c.getMethod("set"+key.substring(0, 1).toUpperCase() + key.substring(1),String.class); + if(setter!=null){ + setter.invoke(instance, value); + } + } + Method executeMethod = c.getMethod("execute"); + Object result = executeMethod.invoke(instance,null); + view.setJsp(resultMap.get(result)); + + Map paramters = new HashMap(); + Method[] methods = c.getMethods(); + for (Method m:methods) { + String methodName = m.getName(); + if(methodName.startsWith("get")){ + String key = methodName.replace("get","").toLowerCase(); + paramters.put(key,m.invoke(instance,null).toString()); + } + } + view.setParameters(paramters); + } catch (Exception e) { + e.printStackTrace(); + } + }else{ + try { + throw new ClassNotFoundException(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + return view; + } + public static Map> readStrutsXml(){ + SAXReader reader = new SAXReader(); + Map> strutsMap = new HashMap>(); + try { + String path = System.getProperty("user.dir"); + Document document = reader.read(new File(path+"\\src\\main\\java\\com\\github\\wdn\\coding2017\\coderising\\litestruts\\struts.xml")); + Element root = document.getRootElement(); + for (Iterator i = root.elementIterator(); i.hasNext(); ) { + Map actionMap = new HashMap(); + Element actionElement = (Element) i.next(); + if(actionElement.getName().equals("action")){ + actionMap.put("name",actionElement.attributeValue("name")); + actionMap.put("class",actionElement.attributeValue("class")); + } + Map resultMap = new HashMap(); + for (Iterator j=actionElement.elementIterator();j.hasNext();){ + Element resultElement = (Element)j.next(); + resultMap.put(resultElement.attributeValue("name"), resultElement.getText()); + actionMap.put("result", resultMap); + } + strutsMap.put(actionElement.attributeValue("name"),actionMap); + } + } catch (DocumentException e) { + e.printStackTrace(); + } + return strutsMap; + } +} diff --git a/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/StrutsTest.java b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..9fee464283 --- /dev/null +++ b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/StrutsTest.java @@ -0,0 +1,43 @@ +package com.github.wdn.coding2017.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/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/View.java b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/View.java new file mode 100644 index 0000000000..31e1805dc7 --- /dev/null +++ b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.github.wdn.coding2017.coderising.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/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/struts.xml b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..fb12bdc239 --- /dev/null +++ b/group24/626451284/src/main/java/com/github/wdn/coding2017/coderising/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/group24/635501270/week1/collections/ArrayList.java b/group24/635501270/week1/collections/ArrayList.java new file mode 100644 index 0000000000..317e5d1e76 --- /dev/null +++ b/group24/635501270/week1/collections/ArrayList.java @@ -0,0 +1,96 @@ +package week1.collections; + +import java.util.Arrays; + +public class ArrayList implements List { + private int size = 0; //声明数组长度 + + private Object[] elementData = new Object[0]; //声明一个Object数组,初始大小为10 + + /** + * 将元素添加到末尾 + */ + public boolean add(Object o){ + ensureCapacity(size+1); + elementData[size] = o; + size++; + return true; + } + + /** + * 将元素插入到index位置 + */ + public void add(int index, Object o){ + exception(index); + ensureCapacity(size+1); + System.arraycopy(elementData, index, elementData, index+1, size-index); + elementData[index] = o; + size++; + } + + /** + * 获得index位置的元素 + */ + public Object get(int index){ + exception(index); + return elementData[index]; + } + + /** + * 删除index位置的元素并返回 + */ + public Object remove(int index){ + exception(index); + Object o = elementData[index]; + System.arraycopy(elementData, index+1, elementData, index, size-index-1); + size--; + return o; + } + + private void exception(int index) { + if(index > size || index < 0){ + throw new ArrayIndexOutOfBoundsException("index"+index+"越界"); + } + } + + /** + * 获取元素个数 + */ + public int size(){ + return size; + } + + /** + * 获取迭代器 + * @return + */ + public Iterator iterator(){ + return new ArrayListIterator(); + } + + private class ArrayListIterator implements Iterator{ + int pos = 0; + @Override + public boolean hasNext() { + return pos elementData.length){ + int newCapacity = Math.max(minCapacity, elementData.length*2); + elementData = Arrays.copyOf(elementData, newCapacity); + } + } +} diff --git a/group24/635501270/week1/collections/BinaryTreeNode.java b/group24/635501270/week1/collections/BinaryTreeNode.java new file mode 100644 index 0000000000..c120fd5f12 --- /dev/null +++ b/group24/635501270/week1/collections/BinaryTreeNode.java @@ -0,0 +1,57 @@ +package week1.collections; + +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){ + if(data == null){ + data = o; + return this; + } + if(o instanceof Integer || this.data instanceof Integer){ + int compare = (Integer)this.data - (Integer)o; + if(compare > 0){ + if(this.left == null){ + this.left = new BinaryTreeNode(); + this.left.data = o; + return this.left; + }else{ + return this.left.insert(o); + } + }else if(compare < 0){ + if(this.right == null){ + this.right = new BinaryTreeNode(); + this.right.data = o; + return this.right; + }else{ + return this.right.insert(o); + } + }else{ + return this; + } + } + return null; + } +} diff --git a/group24/635501270/week1/collections/Iterator.java b/group24/635501270/week1/collections/Iterator.java new file mode 100644 index 0000000000..2fc31b5a3a --- /dev/null +++ b/group24/635501270/week1/collections/Iterator.java @@ -0,0 +1,6 @@ +package week1.collections; + +public interface Iterator { + public boolean hasNext(); + public Object next(); +} diff --git a/group24/635501270/week1/collections/LinkedList.java b/group24/635501270/week1/collections/LinkedList.java new file mode 100644 index 0000000000..bb00b7c3d8 --- /dev/null +++ b/group24/635501270/week1/collections/LinkedList.java @@ -0,0 +1,204 @@ +package week1.collections; + +public class LinkedList implements List { + private int size = 0; + private Node head; + private Node last; + + public boolean add(Object o){ + Node newNode = new Node(o); + if(head == null){ + last = newNode; + head = newNode; + }else{ + Node oldLast = last; + last = newNode; + oldLast.next = last; + } + size++; + return true; + } + public void add(int index , Object o){ + outOfIndex(index); + if(index == 0){ + Node oldHead = head; + head = new Node(o); + head.next = oldHead; + }else{ + Node h = getNode(index-1); + Node newNode = new Node(o); + newNode.next = h.next; + h.next = newNode; + } + size++; + } + public Object get(int index){ + Node h = getNode(index); + return h.data; + } + private Node getNode(int index) { + outOfIndex(index); + Node h = head; + for(int i=0;i= size || index < 0){ + throw new IndexOutOfBoundsException("Index"+index+"越界"); + } + } + public Object remove(int index){ + outOfIndex(index); + Object data; + if(index==0){ + Node oldHead = head; + head = head.next; + data = oldHead.data; + oldHead = null; + }else{ + Node preNode = getNode(index-1); + if(preNode.next==last){ + Node oldLast = last; + last = preNode; + data = oldLast.data; + oldLast = null; + }else{ + Node removeNode = preNode.next; + preNode.next = preNode.next.next; + data = removeNode.data; + removeNode = null; + } + } + size--; + return data; + } + + public int size(){ + return size; + } + + public void addFirst(Object o){ + add(0,o); + } + public void addLast(Object o){ + if(last==null){ + add(o); + }else{ + Node oldLast = last; + last = new Node(o); + oldLast.next = last; + } + size++; + } + public Object removeFirst(){ + return remove(0); + } + public Object removeLast(){ + return remove(size-1); + } + public Iterator iterator(){ + return new LinkedListIterator(); + } + private class LinkedListIterator implements Iterator{ + int pos = 0; + @Override + public boolean hasNext() { + return pos7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int 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){ + 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; + } +} diff --git a/group24/635501270/week1/collections/List.java b/group24/635501270/week1/collections/List.java new file mode 100644 index 0000000000..248fb2e27f --- /dev/null +++ b/group24/635501270/week1/collections/List.java @@ -0,0 +1,9 @@ +package week1.collections; + +public interface List { + public boolean 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/group24/635501270/week1/collections/Queue.java b/group24/635501270/week1/collections/Queue.java new file mode 100644 index 0000000000..b1f431deeb --- /dev/null +++ b/group24/635501270/week1/collections/Queue.java @@ -0,0 +1,24 @@ +package week1.collections; + +public class Queue { + + private LinkedList list = new LinkedList(); + + public boolean enQueue(Object o){ + list.add(o); + return true; + } + + public Object deQueue(){ + Object o = list.removeFirst(); + return o; + } + + public boolean isEmpty(){ + return list.size()==0; + } + + public int size(){ + return list.size(); + } +} diff --git a/group24/635501270/week1/collections/Stack.java b/group24/635501270/week1/collections/Stack.java new file mode 100644 index 0000000000..e25d6491eb --- /dev/null +++ b/group24/635501270/week1/collections/Stack.java @@ -0,0 +1,25 @@ +package week1.collections; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + elementData.add(o); + } + + public Object pop(){ + Object o = elementData.remove(elementData.size()-1); + return o; + } + + public Object peek(){ + Object o = elementData.get(elementData.size()-1); + return o; + } + public boolean isEmpty(){ + return elementData.size()==0; + } + public int size(){ + return elementData.size(); + } +} diff --git a/group24/635501270/week1/collectiontest/ArrayListTest.java b/group24/635501270/week1/collectiontest/ArrayListTest.java new file mode 100644 index 0000000000..d71f1d63da --- /dev/null +++ b/group24/635501270/week1/collectiontest/ArrayListTest.java @@ -0,0 +1,43 @@ +package week1.collectiontest; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import week1.collections.ArrayList; +import week1.collections.Iterator; + +public class ArrayListTest { + ArrayList list; + @Before + public void init(){ + list = new ArrayList(); + for(int i=1;i<=10;i++){ + list.add(i); + } + } + + @Test + public void test1(){ + list.add(4,4.5); + assertEquals(4.5, list.get(4)); + } + + @Test + public void test2(){ + for(int i=10;i>=1;i--){ + assertEquals(i, list.remove(i-1)); + } + } + + @Test + public void test3(){ + Iterator it = list.iterator(); + while(it.hasNext()){ + for(int i=1;i<=10;i++){ + assertEquals(it.next(), i); + } + } + } +} diff --git a/group24/635501270/week1/collectiontest/BinaryTreeNodeTest.java b/group24/635501270/week1/collectiontest/BinaryTreeNodeTest.java new file mode 100644 index 0000000000..fa0984130c --- /dev/null +++ b/group24/635501270/week1/collectiontest/BinaryTreeNodeTest.java @@ -0,0 +1,36 @@ +package week1.collectiontest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import week1.collections.BinaryTreeNode; + +public class BinaryTreeNodeTest { + BinaryTreeNode BTN = null; + @Before + public void init(){ + BTN = new BinaryTreeNode(); + } + + @Test + public void test1(){ + Object o = BTN.getData(); + Assert.assertEquals(null, o); + } + + @Test + public void test2(){ + Object o1 = BTN.insert(5).getData(); + Assert.assertEquals(o1, 5); + Object o2 = BTN.insert(7).getData(); + Assert.assertEquals(o2, 7); + Object o3 = BTN.insert(1).getData(); + Assert.assertEquals(o3, 1); + Assert.assertEquals(5, BTN.getData()); + Assert.assertEquals(7, BTN.getRight().getData()); + Assert.assertEquals(1, BTN.getLeft().getData()); + BTN.insert(6).getData(); + Assert.assertEquals(6, BTN.getRight().getLeft().getData()); + } +} diff --git a/group24/635501270/week1/collectiontest/LinkedListTest.java b/group24/635501270/week1/collectiontest/LinkedListTest.java new file mode 100644 index 0000000000..d4c94b6d61 --- /dev/null +++ b/group24/635501270/week1/collectiontest/LinkedListTest.java @@ -0,0 +1,87 @@ +package week1.collectiontest; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +import week1.collections.Iterator; +import week1.collections.LinkedList; + +public class LinkedListTest { + LinkedList list; + @Before + public void init(){ + list = new LinkedList(); + for(int i=1;i<=10;i++){ + list.add(i); + } + } + + @Test + public void test1(){ + for(int i=1;i<=10;i++){ + assertEquals(i, list.get(i-1)); + } + } + + @Test + public void test2(){ + list.add(0,4.5); + assertEquals(list.get(0), 4.5); + assertEquals(list.get(1), 1); + } + + @Test + public void test3(){ + assertEquals(list.remove(0), 1); + assertEquals(list.get(5), 7); + assertEquals(list.remove(4), 6); + System.out.println(list.size()); + } + + @Test + public void test4(){ + list.addFirst(0.5); + list.addLast(10.5); + assertEquals(list.get(0),0.5); + assertEquals(list.get(11), 10.5); + } + + @Test + public void test5(){ + assertEquals(list.remove(9), 10); + list.addLast(10.5); + assertEquals(list.get(9), 10.5); + list.addFirst(1.5); + assertEquals(list.get(0), 1.5); + } + + @Test + public void test6(){ + assertEquals(list.removeFirst(), 1); + assertEquals(list.removeLast(),10); + list.addFirst(55); + list.addLast(100); + assertEquals(list.get(0), 55); + assertEquals(list.get(9), 100); + } + + @Test + public void test7(){ + Iterator it = list.iterator(); + while(it.hasNext()){ + for(int i=1;i<=10;i++){ + assertEquals(it.next(), i); + } + } + } + + @Test + public void test8(){ + for(int i=1;i<=10;i++){ + assertEquals(list.removeFirst(), i); + System.out.println(list.size()); + } + } +} diff --git a/group24/635501270/week1/collectiontest/QueueTest.java b/group24/635501270/week1/collectiontest/QueueTest.java new file mode 100644 index 0000000000..e679d857a4 --- /dev/null +++ b/group24/635501270/week1/collectiontest/QueueTest.java @@ -0,0 +1,31 @@ +package week1.collectiontest; + +import static org.junit.Assert.*; + +import java.awt.List; + +import org.junit.Before; +import org.junit.Test; + +import week1.collections.Queue; + +public class QueueTest { + Queue queue = null; + @Before + public void init(){ + queue = new Queue(); + for(int i=1;i<=10;i++){ + queue.enQueue(i); + } + } + + @Test + public void test1(){ + for(int i=1;i<=10;i++){ + System.out.println(queue.size()); + assertEquals(queue.deQueue(), i); + } + assertEquals(queue.isEmpty(), true); + } + +} diff --git a/group24/635501270/week1/collectiontest/StackTest.java b/group24/635501270/week1/collectiontest/StackTest.java new file mode 100644 index 0000000000..d2f5921b79 --- /dev/null +++ b/group24/635501270/week1/collectiontest/StackTest.java @@ -0,0 +1,36 @@ +package week1.collectiontest; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +import week1.collections.Stack; + +public class StackTest { + Stack stack = null; + @Before + public void init(){ + stack = new Stack(); + for(int i=1;i<=10;i++){ + stack.push(i); + } + } + + @Test + public void test1(){ + assertEquals(stack.peek(), 10); + assertEquals(stack.peek(), 10); + assertEquals(stack.peek(), 10); + assertEquals(stack.pop(), 10); + assertEquals(stack.pop(), 9); + assertEquals(stack.size(), 8); + } + + @Test + public void test2(){ + for(int i=10;i>=1;i--){ + assertEquals(stack.pop(), i); + } + assertEquals(stack.isEmpty(), true); + } +} diff --git a/group24/815591664/2017Learning/src/com/coderising/array/ArrayUtil.java b/group24/815591664/2017Learning/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..7c30103d89 --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,348 @@ +package com.coderising.array; + +import java.util.ArrayList; +import java.util.Arrays; + +import java.util.List; + + +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 main(String[] args) { + int[] a = {7, 9, 30, 3, 4}; + reverseArray(a); + System.out.println(Arrays.toString(a)); + + + int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5,0} ; + System.out.println(Arrays.toString(removeZero(oldArr))); + + + int[] a1 = {3, 5, 7,8}; + int[] a2 = {4, 5, 6,7}; + + System.out.println(Arrays.toString(merge(a1,a2))); + + + int[] b = { 2,3,6}; + System.out.println(Arrays.toString(grow(b,5))); + + System.out.println(genFibonacci(5)); + + System.out.println(Arrays.toString(fibonacci(30))); + + System.out.println(Arrays.toString(getPrimes(10000))); + + System.out.println(getFactor(10)); + + System.out.println(isPerfectNum(1000)); + +// System.out.println(); + System.out.println(Arrays.toString(getPerfectNumbers(100))); + + System.out.println(join(a,"&")); + + + } + public static void reverseArray(int[] origin){ + + if(origin.length==0){ + return; + + } + int[] copy = new int[origin.length]; + System.arraycopy(origin, 0, copy, 0, origin.length); + + for (int i = 0; i < copy.length; i++) { + + origin[i] = copy[copy.length-1-i]; + } + + + } + + /** + * 现在有如下的一个数组: 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){ + int newSize = 0; + for (int i = 0; i < oldArray.length; i++) { + if(oldArray[i]!=0){ + newSize++; + } + } + int index = 0; + int[] newArr = new int[newSize]; + for (int i = 0; i < oldArray.length; i++) { + if(oldArray[i]!=0){ + newArr[index] = oldArray[i]; + index++; + } + } + return newArr; + } + + /** + * 给定两个已经排序好的整形数组, 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){ + Arrays.sort(array1); + Arrays.sort(array2); + + int[] newArr = new int[array1.length+array2.length]; + + System.arraycopy(array1, 0, newArr, 0,array1.length ); + System.arraycopy(array2, 0, newArr, array1.length, array2.length); + Arrays.sort(newArr); + List list = new ArrayList(); + for(int i=0;i list = new ArrayList(); + for(int i =0;i list = new ArrayList(); + for(int i=2;i<=max;i++){ + if(isPrime(i)){ + list.add(i); + } + } + + return listToArray(list); + + + } + + public static int[] listToArray(List list){ + if(list == null){ + return null; + } + + int[] arr = new int[list.size()]; + + for(int i=0;i list = new ArrayList(); + for(int i=1;i<=max;i++){ + if(isPerfectNum(i)){ + list.add(i); + } + } + + return listToArray(list); + } + + + public static boolean isPerfectNum(int num){ + if(num <=1){ + return false; + } + + List factors = getFactor(num); + int sum = 0; + for (Integer integer : factors) { + sum = integer+sum; + } + if(sum == num){ + return true; + } + return false; + } + + public static List getFactor(int num){ + List list = new ArrayList(); + list.add(1); + + + for(int i=2;i getFactor(int num){ + List list = new ArrayList(); + list.add(1); + int temp = num; + + while(!isPrime(temp)){ + if(temp ==1){ + break; + } + for(int i=2;i<=temp;i++){ + if(temp % i ==0){ + list.add(i); + temp = temp/i; + break; + } + } + + } + list.add(temp); + + return list; + }*/ + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public static String join(int[] array, String seperator){ + StringBuilder sb = new StringBuilder(); + for (int i : array) { + sb.append(i); + sb.append(seperator); + + } + + return sb.subSequence(0, sb.length()-1).toString(); + } + + +} diff --git a/group24/815591664/2017Learning/src/com/coderising/litestruts/LoginAction.java b/group24/815591664/2017Learning/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group24/815591664/2017Learning/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/group24/815591664/2017Learning/src/com/coderising/litestruts/Struts.java b/group24/815591664/2017Learning/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..550d47ec2b --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,137 @@ +package com.coderising.litestruts; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; +import org.jdom2.output.XMLOutputter; + +import com.sun.istack.internal.Builder; + + + +public class Struts { + + @SuppressWarnings("deprecation") + 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字段中。 + + */ + View view = new View(); + String xmlpath = Struts.class.getResource("struts.xml").getFile(); + SAXBuilder builder = null; + try { + xmlpath = URLDecoder.decode(xmlpath, "utf-8"); + builder = new SAXBuilder(false); + Document doc = builder.build(xmlpath); + Element root = doc.getRootElement(); + Element action = root.getChild("action"); + String className = action.getAttributeValue("class"); + Class clazz = Class.forName(className); + Object logAction = clazz.newInstance(); + for(String key :parameters.keySet()){ + String methodName = "set"+ Struts.captureName(key); + Method method = null; + try { + method = clazz.getMethod(methodName, String.class); + } catch (SecurityException e) { + e.printStackTrace(); + break; + } catch (NoSuchMethodException e) { + break; + } + method.invoke(logAction, parameters.get(key)); + + } + Method executeMethod = clazz.getMethod("execute", (Class[])null); + String result = (String)executeMethod.invoke(logAction, (Object[])null); + Method[] declareMtds = clazz.getDeclaredMethods(); + Map paramForView = new HashMap(); + for (Method method : declareMtds) { + String methodName = method.getName(); + if(methodName.startsWith("get")){ + paramForView.put(methodName.substring(3).toLowerCase(), (String)method.invoke(logAction, (Object[])null)); + } + + } + view.setParameters(paramForView); + List results = action.getChildren("result"); + for (Element element : results) { + String resultName = element.getAttributeValue("name"); + if(result.equals(resultName)){ + view.setJsp(element.getText()); + } + } + + } catch (JDOMException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return view; + } + + + public static String captureName(String name) { + // name = name.substring(0, 1).toUpperCase() + name.substring(1); +// return name; + char[] cs=name.toCharArray(); + cs[0]-=32; + return String.valueOf(cs); + + + } + +} diff --git a/group24/815591664/2017Learning/src/com/coderising/litestruts/StrutsTest.java b/group24/815591664/2017Learning/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group24/815591664/2017Learning/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/group24/815591664/2017Learning/src/com/coderising/litestruts/View.java b/group24/815591664/2017Learning/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coderising/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coderising.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/group24/815591664/2017Learning/src/com/coding/basic/ArrayList.java b/group24/815591664/2017Learning/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..e5fec6fceb --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coding/basic/ArrayList.java @@ -0,0 +1,134 @@ +package com.coding.basic; + +import java.util.Arrays; +import java.util.LinkedList; + +/** + * @author hugaoqing + * created on 2017-3-8 + */ +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData = new Object[3]; + + /* + * 添加元素 + * + */ + public void add(Object o){ + /*if(elementData.length == size){ + Object[] buffer = new Object[size+15]; + System.arraycopy(elementData, 0, buffer, 0, size); + elementData = buffer; + elementData[size] = o; + size++; + }else { + + elementData[size] = o; + size++; + }*/ + add(size, o); + + } + + + /* + * + * 指定位置添加元素 + */ + public void add(int index, Object o){ + if(index <0 || index > size){ + throw new IndexOutOfBoundsException(); + } + if(size+1=size){ + throw new IndexOutOfBoundsException(); + } + return elementData[index]; + } + + public Object remove(int index){ + if(index<0||index>=size){ + throw new IndexOutOfBoundsException(); + } + Object out = elementData[index]; + Object[] temp = new Object[size-index-1]; + System.arraycopy(elementData, index+1, temp, 0, size-index-1); + System.arraycopy(temp, 0, elementData,index, size-index-1); + //将移除的元素的指针去掉,避免内存泄漏 + elementData[size-1] = null; + size--; + return out; + } + + public int size(){ + return this.size; + } + + @Override + public String toString() { + Object[] objs = new Object[size]; + System.arraycopy(elementData, 0,objs , 0, size); + return Arrays.toString(objs); + + } + public Iterator iterator(){ + return new Iterator() { + int cursor = 0; + public Object next() throws Exception { + cursor++; + return get(cursor-1); + } + + public boolean hasNext() { + + return this.cursor0){ + while(curNode.getRight()!=null){ + curNode = curNode.getRight(); + } + curNode = node; + + }else{ + while(curNode.getLeft()!=null){ + curNode = curNode.getLeft(); + } + curNode = node; + } + + } + return null; + } + +} diff --git a/group24/815591664/2017Learning/src/com/coding/basic/BinaryTreeNode.java b/group24/815591664/2017Learning/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..4bd92572c9 --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coding/basic/BinaryTreeNode.java @@ -0,0 +1,109 @@ +package com.coding.basic; + + + +/** + * @author hugaoqing + * created on 2017-3-11 + */ +public class BinaryTreeNode { + + private Comparable data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public BinaryTreeNode(Comparable data2) { + // TODO Auto-generated constructor stub + } + public BinaryTreeNode() { + // TODO Auto-generated constructor stub + } + /*public BinaryTreeNode(Comparable data) { + super(); + this.data = data; + }*/ + public Comparable getData() { + return data; + } + public void setData(Comparable 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(Comparable data){ + /*if(this.data==null){ + return new BinaryTreeNode(o); + } + + BinaryTreeNode curNode = this; + while(curNode != null){ + if(curNode.data.compareTo(o) == 0){ + return curNode; + } + else if(o.compareTo(curNode.data) < 0){ + BinaryTreeNode node = curNode; + curNode = curNode.left; + if(curNode == null){ + curNode = new BinaryTreeNode(o); + node.left = curNode; + return curNode; + } + + + }else if(o.compareTo(curNode.data) > 0){ + BinaryTreeNode node = curNode; + curNode = curNode.right; + if(curNode == null){ + curNode = new BinaryTreeNode(o); + node.right = curNode; + return curNode; + } + } + } + return curNode;*/ + BinaryTreeNode curNode = this; + BinaryTreeNode insertNode = new BinaryTreeNode(); + insertNode.setData(data); + + while(curNode != null){ + if(null == curNode.data){ + curNode.setData(data); + break; + }else{ + Comparable dataOfNode = curNode.getData(); + if(dataOfNode.compareTo(data) == 0){ + break; + }else if(dataOfNode.compareTo(data) < 0){ + BinaryTreeNode leftNode = curNode.left; + if(null == leftNode){ + curNode.setLeft(insertNode); + break; + } + curNode = leftNode; + }else{ + BinaryTreeNode rightNode = curNode.right; + if(null == rightNode){ + curNode.setRight(insertNode); + break; + } + curNode = rightNode; + } + } + } + return insertNode; + + + } + +} diff --git a/group24/815591664/2017Learning/src/com/coding/basic/Iterator.java b/group24/815591664/2017Learning/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..d4656a7daf --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coding/basic/Iterator.java @@ -0,0 +1,9 @@ +package com.coding.basic; + +public interface Iterator { + //ӿijԱĬ϶final static +// int cursor = 0; + public boolean hasNext(); + public Object next() throws Exception; + +} diff --git a/group24/815591664/2017Learning/src/com/coding/basic/LinkedList.java b/group24/815591664/2017Learning/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..3d7e06e19f --- /dev/null +++ b/group24/815591664/2017Learning/src/com/coding/basic/LinkedList.java @@ -0,0 +1,223 @@ +package com.coding.basic; + +public class LinkedList implements List { + + private Node head; + private int size; + + + public void add(Object o){ + this.addLast(o); + + } + public void add(int index , Object o){ + if(index<0 || index>size){ + throw new IndexOutOfBoundsException(); + } + if(index==0){ + this.addFirst(o); + size++; + return; + }else if(index==size){ + this.addLast(o); + size++; + return; + } + Node preNode = this.getNode(index-1); + Node curNode = this.getNode(index); + Node newNode = new Node(o, curNode); + preNode.next = newNode; + + + size++; + + + } + + private Node getNode(int index){ + if(index <0 || index>=size){ + throw new IndexOutOfBoundsException(); + } + if(index ==0){ + return head; + } + Node curNode = head; + for(int i=1;i<=index;i++){ + curNode = head.next; + } + return curNode; + } + + public Object get(int index){ + if(index<0 || index>=size){ + throw new IndexOutOfBoundsException(); + } + + Node temp = head; + for(int i =1;i<=index;i++){ + temp = temp.next; + } + return temp.data; + } + public Object remove(int index){ + if(index<0 || index>=size){ + throw new IndexOutOfBoundsException(); + } + Object o = null; + if(size == 1){ + o = head.data; + size--; + return o; + } + if(index==0){ + o = head.data; + Node afterHead = head.next; + head = afterHead; + + }else if(index==size-1){ + Node preTail = getNode(index-1); + Node tail = preTail.next; + o = tail.data; + preTail.next = null; + }else{ + Node preCur = getNode(index-1); + Node cur = preCur.next; + Node nextCur = cur.next; + o = cur.data; + preCur.next = nextCur; + + } + size--; + return o; + + + + + + + + } + + public int size(){ + return this.size; + } + + public void addFirst(Object o){ + Node node = new Node(o,null); + + if(head == null){ + head = node; + size++; + return; + } + head = new Node(o, head); + size++; + + } + public void addLast(Object o){ + //½ڵnextָָtail + Node add = new Node(o, null); + if(head==null){ + head = add; + size++; + return; + } + Node curNode = head; + while(curNode.next != null){ + curNode = curNode.next; + } + + curNode.next = add; + size++; + } + + + public Object removeFirst() throws Exception{ + return this.remove(0); + } + public Object removeLast() throws Exception{ + return this.remove(size-1); + } + + private class Itr implements Iterator{ + int cursor = 0; + public boolean hasNext() { + return cursor 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() { + + + } + +} diff --git a/group27/1016908591/week03/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group27/1016908591/week03/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..8b7e9cc665 --- /dev/null +++ b/group27/1016908591/week03/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package com.coderising.download.impl; + +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/group27/1016908591/week03/src/com/coderising/download/test/ConnectionTest.java b/group27/1016908591/week03/src/com/coderising/download/test/ConnectionTest.java new file mode 100644 index 0000000000..6c127cb054 --- /dev/null +++ b/group27/1016908591/week03/src/com/coderising/download/test/ConnectionTest.java @@ -0,0 +1,57 @@ +package com.coderising.download.test; + +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.impl.ConnectionManagerImpl; + +public class ConnectionTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + //测试连接url的功能 + public void testContentLength() throws Exception{ + //new一个接口,然后实现这个接口 + 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 + //测试读入,确保设计的接口ok + 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); + + + // 测试不充分,没有断言内容是否正确 + } + + + + +} diff --git a/group27/1016908591/week03/src/com/coderising/download/test/FileDownloaderTest.java b/group27/1016908591/week03/src/com/coderising/download/test/FileDownloaderTest.java new file mode 100644 index 0000000000..40f01fd9ac --- /dev/null +++ b/group27/1016908591/week03/src/com/coderising/download/test/FileDownloaderTest.java @@ -0,0 +1,66 @@ +package com.coderising.download.test; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.FileDownloader; +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() { + /*题 一般的时候是网络连接的问题。还有你可以设置一下 服务器的超时时间。有的可能是三十秒。你试试更长点的。 + * 还有一种可能性是。你程序里创建了很多connection 但是没有关闭调。现在数据库处于半死状态,然后连接超时。 + * 你ping的是服务器的ip吗? 你可以用plsql检验一下你的网络是否通。还有配置服务器数据源的时候 如果能配置成功, + * 那网络也没问题。 + */ + //String url = "http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + + String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + + FileDownloader downloader = new FileDownloader(url,"e:\\项目练手\\test.jpg"); + + + 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/group27/1016908591/week03/src/com/coding/basic/LinkedList.java b/group27/1016908591/week03/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..8efd566a00 --- /dev/null +++ b/group27/1016908591/week03/src/com/coding/basic/LinkedList.java @@ -0,0 +1,283 @@ +package com.coding.basic; +import javax.xml.crypto.Data; + + + +public class LinkedList implements List { + + private Node head; + private int length; + //构造函数 + public LinkedList(){ + clear(); + } + public final void clear(){ + head = null; + length = 0; + } + + public void add(Object o){ + Node newNode = new Node(o); + if(length == 0) + { + head = newNode; + } + else{ + Node lastNode = getNodeAt(length); + lastNode.next = newNode; + + } + length++; + + + } + public void add(int index , Object o){ + Node newNode = new Node(o); + Node nodeBefor = getNodeAt(index-1); + Node nodeAfter = nodeBefor.next; + newNode.next = nodeAfter; + nodeBefor.next = newNode; + length++; + + + } + public Object get(int index){ + if((1<=index)&&(index<=length)) + { + Node currentNode = head; + for(int i= 0;i7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + Node lastNode = getNodeAt(length); + head = lastNode; + while(length>0){ + Node currentNode = getNodeAt(--length); + add(currentNode); + + } + + + + + + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int num = length/2; + while(num>0){ + remove(num); + num--; + } + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + while (length>0){ + remove(i+length); + length--; + } + + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] arr = new int[list.size()]; + + for(int i =0;idata) + remove(i); + } + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + if(list==null){ + return null; + } + int i1 = 0; + int i2 = 0; + LinkedList result = new LinkedList(); + Node currentListNode = list.head; + Node currentThisNode = this.head; + for(i1 =0;i1 list; @Before diff --git a/group27/1252327158/task1_20170312/src/com/coding/LinkedList.java b/group27/1252327158/task1_20170312/src/com/coding/LinkedList.java index 168bb07592..7226968638 100644 --- a/group27/1252327158/task1_20170312/src/com/coding/LinkedList.java +++ b/group27/1252327158/task1_20170312/src/com/coding/LinkedList.java @@ -183,7 +183,16 @@ public Node(T data, Node node) { * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ - + if (size <= 1) { + return; + } + Node node = head; + while (node.next != null) { + Node temp = node.next; + node.next = temp.next; + temp.next = head; + head = temp; + } } /** @@ -193,7 +202,11 @@ public void reverse(){ */ public void removeFirstHalf(){ - + if (size < 2) { + return; + } + int delSize = (int)Math.floor(size/2); + remove(0, delSize); } /** @@ -202,8 +215,31 @@ public void removeFirstHalf(){ * @param length */ public void remove(int i, int length){ + if (i < 0 || i >= size || length < 0 || i + length > size) { + throw new IndexOutOfBoundsException(); + } + if (i == 0) { + head = removeStartWith(head, length); + return; + } + Node beforeStart = head; //被删除元素的前一个 + for (int index = 1; index < i; index++) { + beforeStart = beforeStart.next; + } + beforeStart.next = removeStartWith(beforeStart.next, length); + } + private Node removeStartWith(Node startNode, int length) { + Node node = null; + for (int index = 1; index <= length; index++) { + node = startNode; + startNode = startNode.next; + node.next = null; + size--; + } + return startNode; } + /** * 假定当前链表和list均包含已升序排列的整数 * 从当前链表中取出那些list所指定的元素 @@ -212,8 +248,29 @@ public void remove(int i, int length){ * 返回的结果应该是[101,301,401,601] * @param list */ - public static int[] getElements(LinkedList list){ - return null; + public int[] getElements(LinkedList list){ + if (size == 0 || list == null || list.size == 0) { + return new int[0]; + } + int[] result = new int[list.size]; + Node node = head; + int index = 0; + int resultIndex = 0; + for (int i = 0; i < size; i++ ) { + int listData = ((Integer)list.get(index)).intValue(); + if ( listData >= size) { + throw new IndexOutOfBoundsException(); + } + if (i == listData) { + result[resultIndex++] = ((Integer)node.data).intValue(); + index++; + } + if (index == list.size || listData == size) { + break; + } + node = node.next; + } + return result; } /** @@ -224,7 +281,35 @@ public static int[] getElements(LinkedList list){ */ public void subtract(LinkedList list){ - + if (list == null || list.size() == 0) { + return; + } + Node node = head; + Node beforeNode = null; + Node temp = null; + int j = 0; //参数list索引 + for (;node != null && j < list.size() ;) { + int paradata = ((Integer)list.get(j)).intValue(); + int data = ((Integer)node.data).intValue(); + if (data == paradata) { + j++; + size--; + temp = node; + if (beforeNode == null) { + head = node.next; + node = node.next; + } else {; + beforeNode.next = node.next; + node = node.next; + } + temp.next = null; + } else if (data < paradata) { + beforeNode = node; + node = node.next; + } else { + j++; + } + } } /** @@ -232,7 +317,21 @@ public void subtract(LinkedList list){ * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ - + if (size < 2) { + return; + } + Node node = head; + Node delNode = null; + while (node.next != null) { + if (((Integer)node.next.data).equals(node.data)) { + delNode = node.next; + node.next = node.next.next; + delNode.next = null; + size--; + } else { + node = node.next; + } + } } /** @@ -242,7 +341,27 @@ public void removeDuplicateValues(){ * @param max */ public void removeRange(int min, int max){ - + if (min >= max) { + return; + } + Node node = head; + int delLen = 0; + int startIndex = -1; + for (int i = 0; i < size; i++) { + int currentData = ((Integer)node.data).intValue(); + if (currentData > min && currentData < max) { + if (delLen == 0) { + startIndex = i; + } + delLen++; + } else if (currentData >= max) { + break; + } + node = node.next; + } + if (delLen > 0) { + remove(startIndex, delLen); + } } /** @@ -251,6 +370,24 @@ public void removeRange(int min, int max){ * @param list */ public LinkedList intersection( LinkedList list){ - return null; + if (list.size() == 0 || size == 0) { + return null; + } + LinkedList result = new LinkedList(); + Node node = head; + Iterator listIter = list.iterator(); + while (listIter.hasNext()) { + int listData = ((Integer)listIter.next()).intValue(); + for (;node != null;) { + int currentData = ((Integer)node.data).intValue(); + if (currentData == listData) { + result.addLast(currentData); + } else if (currentData > listData) { + break; + } + node = node.next; + } + } + return result; } } diff --git a/group27/1252327158/task1_20170312/src/com/coding/LinkedListTest.java b/group27/1252327158/task1_20170312/src/com/coding/LinkedListTest.java index 03f7198998..c9a2504964 100644 --- a/group27/1252327158/task1_20170312/src/com/coding/LinkedListTest.java +++ b/group27/1252327158/task1_20170312/src/com/coding/LinkedListTest.java @@ -8,7 +8,8 @@ import org.junit.Test; public class LinkedListTest { - LinkedList list; + + LinkedList list; @Before public void setUp() throws Exception { @@ -92,4 +93,118 @@ public void testIterator() { } } + @Test + public void reverse() throws Exception { + list.add("third"); + list.add("forth"); + Assert.assertEquals("forth", list.get(0)); + list.reverse(); + Assert.assertEquals("first", list.get(0)); + Assert.assertEquals("second", list.get(1)); + Assert.assertEquals("third", list.get(2)); + Assert.assertEquals("forth", list.get(3)); + } + + @Test + public void removeFirstHalf() throws Exception { + list.add("third"); + list.add("forth"); + list.removeFirstHalf(); + Assert.assertEquals("second", list.get(0)); + Assert.assertEquals(2, list.size()); + } + + @Test + public void remove() throws Exception { + list.add("third"); + list.add("forth"); + list.remove(1, 2); + Assert.assertEquals("forth", list.get(0)); + Assert.assertEquals("first", list.get(1)); + } + + @Test + public void getElements() throws Exception { + LinkedList intList = new LinkedList<>(); + intList.addLast(11); + intList.addLast(101); + intList.addLast(201); + intList.addLast(301); + intList.addLast(401); + intList.addLast(501); + intList.addLast(601); + intList.addLast(701); + LinkedList searchList = new LinkedList<>(); + searchList.addLast(1); + searchList.addLast(3); + searchList.addLast(4); + searchList.addLast(7); + + Assert.assertArrayEquals(new int[]{101,301,401,701}, intList.getElements(searchList)); + } + + @Test + public void subtract() throws Exception { + LinkedList intList = new LinkedList<>(); + intList.addLast(11); + intList.addLast(101); + intList.addLast(201); + intList.addLast(301); + intList.addLast(401); + LinkedList delList= new LinkedList<>(); + delList.addLast(11); + delList.addLast(101); + delList.addLast(301); + delList.addLast(401); + intList.subtract(delList); + Assert.assertEquals(201, ((Integer)intList.get(0)).intValue()); + Assert.assertEquals(1, intList.size()); + } + + @Test + public void removeDuplicateValues() throws Exception { + LinkedList intList = new LinkedList<>(); + intList.addLast(11); + intList.addLast(101); + intList.addLast(101); + intList.addLast(101); + intList.addLast(401); + intList.removeDuplicateValues(); + Assert.assertEquals(11, ((Integer)intList.get(0)).intValue()); + Assert.assertEquals(101, ((Integer)intList.get(1)).intValue()); + Assert.assertEquals(401, ((Integer)intList.get(2)).intValue()); + Assert.assertEquals(3, intList.size()); + } + + @Test + public void removeRange() throws Exception { + LinkedList intList = new LinkedList<>(); + intList.addLast(11); + intList.addLast(101); + intList.addLast(201); + intList.addLast(301); + intList.addLast(401); + intList.removeRange(11, 301); + Assert.assertEquals(3, intList.size()); + Assert.assertEquals(11, ((Integer)intList.get(0)).intValue()); + Assert.assertEquals(301, ((Integer)intList.get(1)).intValue()); + } + + @Test + public void intersection() throws Exception { + LinkedList intList = new LinkedList<>(); + intList.addLast(11); + intList.addLast(101); + intList.addLast(201); + intList.addLast(301); + intList.addLast(401); + LinkedList paraList= new LinkedList<>(); + paraList.addLast(11); + paraList.addLast(301); + paraList.addLast(501); + LinkedList newList = intList.intersection(paraList); + Assert.assertEquals(2, newList.size()); + Assert.assertEquals(11, ((Integer)newList.get(0)).intValue()); + Assert.assertEquals(301, ((Integer)newList.get(1)).intValue()); + } } diff --git a/group27/1252327158/task2_20170319/litestruts/src/com/coderising/litestruts/Struts.java b/group27/1252327158/task2_20170319/litestruts/src/com/coderising/litestruts/Struts.java index ce0ec1a04c..3d5ed76bb3 100644 --- a/group27/1252327158/task2_20170319/litestruts/src/com/coderising/litestruts/Struts.java +++ b/group27/1252327158/task2_20170319/litestruts/src/com/coderising/litestruts/Struts.java @@ -39,17 +39,28 @@ public static View runAction(String actionName, Map parameters) { */ - XMLHandle xmlHandle; + Document document = null; Class action = null; Object object = null; - + try { + SAXReader saxReader = new SAXReader(); + document = saxReader.read(new File("struts.xml")); // 读取XML文件,获得document对象 + Element root = document.getRootElement(); + for (Iterator it = root.elementIterator(); it.hasNext();) { + Element element = it.next(); + if (element.attribute("name").getValue().equals(actionName)) { + String className = element.attribute("class").getValue(); + action = Class.forName(className); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + if (action == null) { + return null; + } + try { - xmlHandle = new XMLHandle(); - String className = xmlHandle.getClassName(actionName); - if (className == null) { - return null; - } - action = Class.forName(className); object = action.newInstance(); Iterator> mapIt = parameters.entrySet().iterator(); while (mapIt.hasNext()) { @@ -58,28 +69,35 @@ public static View runAction(String actionName, Map parameters) { for (Method method : methods) { if (method.getName().equalsIgnoreCase("set" + entry.getKey())) { method.invoke(object, entry.getValue()); + break; } - } + } +// methods = action.getDeclaredMethods(); +// for (Method method : methods) { +// if (method.getName().equalsIgnoreCase("get" + entry.getKey())) { +// String name = (String)method.invoke(object); +// System.out.println(name); +// break; +// } +// } } - + } + } + Method execute = action.getDeclaredMethod("execute"); String result = (String)execute.invoke(object); - Field[] fields = action.getDeclaredFields(); + Method[] methods = action.getMethods(); Map map = new HashMap(); - for (Field field : fields) { - Method[] methods = action.getMethods(); - for (Method method : methods) { - if (method.getName().equalsIgnoreCase("get" + field.getName())) { - map.put(field.getName(), (String)method.invoke(object)); - } + for (Method method : methods) { + if (method.getName().startsWith("get")) { + map.put(method.getName().substring(3).toLowerCase(), (String)method.invoke(object)); } } + View view = new View(); - view.setParameters(map); - String jspResult = xmlHandle.getResult(actionName, result); - view.setJsp(jspResult); - return view; + view.setParameters(map); + return view; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { @@ -92,10 +110,6 @@ public static View runAction(String actionName, Map parameters) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); - } catch (DocumentException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/DownloadThread.java b/group27/1252327158/task3_20170326/download/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..58b8a4e3a6 --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/DownloadThread.java @@ -0,0 +1,79 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread{ + + private int endPos; + private int startPos; + private String url; + private String destFilePath; + private ConnectionManager connManager; + private DownloadListener downloadListener; + + public DownloadThread(ConnectionManager connManager, String url, int startPos, int endPos, String destFilePath, + DownloadListener downloadListener) { + + this.url = url; + this.endPos = endPos; + this.startPos = startPos; + this.connManager = connManager; + this.destFilePath = destFilePath; + this.downloadListener = downloadListener; + } + + @Override + public void run() { + Connection conn = null; + RandomAccessFile randomAccessFile = null; + try { + doLog("BIN"); + conn = connManager.open(url, startPos, endPos); + byte[] read = conn.read(startPos, endPos); + String _filePath = destFilePath; + if (_filePath == null || _filePath.length() == 0) { + _filePath = conn.getFileName(); + } + randomAccessFile = new RandomAccessFile(_filePath, "rw"); + randomAccessFile.seek(startPos); + randomAccessFile.write(read); + doLog("END"); + } catch (IOException e) { + doLog("EXP1"); + e.printStackTrace(); + } catch (com.coderising.download.api.ConnectionException e) { + doLog("EXP2"); + e.printStackTrace(); + } finally { + if (randomAccessFile != null) { + try { + randomAccessFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (conn != null) { + conn.close(); + } + if (downloadListener != null) { + downloadListener.notifyFinished(); + } + } + } + + private void doLog(String action) { + System.out.println( + "*********** " + action + + " [" + + startPos + + "-" + + endPos + + "]" + + " ***********"); + } +} diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloader.java b/group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..ee3a321b81 --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloader.java @@ -0,0 +1,83 @@ +package com.coderising.download; + +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +import java.util.concurrent.atomic.AtomicInteger; + + +public class FileDownloader { + + private String url; + + private DownloadListener listener; + + private ConnectionManager cm; + + private AtomicInteger atomicInteger; + + public FileDownloader(String _url) { + this.url = _url; + atomicInteger = new AtomicInteger(); + } + + /** + * 在这里实现你的代码, 注意: 需要用多线程实现下载 + * 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + * (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方法 + * + * 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + */ + public void execute() { + try { + + int threadCount = 5; + int length = this.cm.getContentLength(this.url); + for (int i = 0; i < threadCount; i++) { + + int threadLoadLength = length / threadCount; + int startPos = threadLoadLength * i; + int endPos; + if (i != threadCount - 1) { + endPos = threadLoadLength * (i + 1) - 1; + } else { + endPos = length - 1; + } + atomicInteger.getAndIncrement(); + new DownloadThread(cm, this.url, startPos, endPos, "download_file.jpeg", new DownloadListener() { + @Override + public void notifyFinished() { + if (atomicInteger.decrementAndGet() == 0) { + if (FileDownloader.this.listener != null) { + FileDownloader.this.listener.notifyFinished(); + } + } + } + }).start(); + } + } catch (ConnectionException e) { + e.printStackTrace(); + } + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return this.listener; + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } +} \ No newline at end of file diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloaderTest.java b/group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..865d65510d --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489721424&di=1fda6467501ab1d5e5bff43e801d14ee&imgtype=jpg&er=1&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201507%2F30%2F20150730163204_A24MX.thumb.700_0.jpeg"; + + 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/group27/1252327158/task3_20170326/download/com/coderising/download/api/Connection.java b/group27/1252327158/task3_20170326/download/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0795bca536 --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/api/Connection.java @@ -0,0 +1,30 @@ +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(); + + /** + * 获取下载文件的文件名 + * + * @return 文件名 + */ + String getFileName(); +} diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionException.java b/group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..bd8934095f --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,11 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + public ConnectionException(Exception e) { + super(e); + } + + public ConnectionException(String msg) { + super(msg); + } +} diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionManager.java b/group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..69321679fa --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,21 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * + * @param url 连接地址 + * @param startPos 读取文件的起始位置 + * @param endPos 读取文件的结束位置 + * @return 连接 + */ + Connection open(String url, int startPos, int endPos) throws ConnectionException; + + /** + * 获取文件长度 + * + * @param url 连接地址 + * @return 文件长度 + */ + int getContentLength(String url) throws ConnectionException; +} diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/api/DownloadListener.java b/group27/1252327158/task3_20170326/download/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionImpl.java b/group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..0a367ea1d1 --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,94 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + + private static final int BUFFER_SIZE = 4096; + private HttpURLConnection httpConn; + private String fileUrl; + private InputStream inputStream; + + public ConnectionImpl(HttpURLConnection httpConn, String fileUrl) { + this.httpConn = httpConn; + this.fileUrl = fileUrl; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + if (endPos < startPos) { + throw new IllegalArgumentException("argument endPos[" + endPos + "] less than startPos[" + startPos + "]"); + } + int bytesNeed2Read = endPos - startPos + 1; + if (bytesNeed2Read > getContentLength()) { + throw new IllegalArgumentException( + "endPos[" + endPos + "] is bigger than content length[" + getContentLength() + "]"); + } + + inputStream = httpConn.getInputStream(); + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[Math.min(bytesNeed2Read, BUFFER_SIZE)]; + int read; + + long startTime = System.currentTimeMillis(); + final long progressInterval = 2000; + while ((read = inputStream.read(buffer)) != -1) { + byteArrayOutputStream.write(buffer, 0, read); + + if (System.currentTimeMillis() - startTime > progressInterval) { + startTime = System.currentTimeMillis(); + System.out.println(String.format(Thread.currentThread().getName() + + " [%.2f%%]", byteArrayOutputStream.size() * 100.0 / bytesNeed2Read) + ); + } + } + System.out.println(String.format(Thread.currentThread().getName() + " [%.2f%%]", 100.0)); + System.out.println("bytes read: " + byteArrayOutputStream.size()); + + return byteArrayOutputStream.toByteArray(); + } + + @Override + public int getContentLength() { + if (httpConn != null) { + return httpConn.getContentLength(); + } + return 0; + } + + @Override + public void close() { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (httpConn != null) { + httpConn.disconnect(); + } + } + + @Override + public String getFileName() { + String disposition = httpConn.getHeaderField("Content-Disposition"); + if (disposition != null) { + // extracts file name from header field + int index = disposition.indexOf("filename="); + if (index > 0) { + return disposition.substring(index + 10, + disposition.length() - 1); + } + } + // extracts file name from URL + return fileUrl.substring(fileUrl.lastIndexOf("/") + 1, + fileUrl.length()); + } +} diff --git a/group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionManagerImpl.java b/group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..e88aa35647 --- /dev/null +++ b/group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,61 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String fileURL, int startPos, int endPos) throws ConnectionException { + try { + System.out.println("try to open file url: " + fileURL); + + URL url = new URL(fileURL); + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + + // 设定读取range + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + System.out.println("Range: bytes=" + startPos + "-" + endPos); + + int responseCode = httpConn.getResponseCode(); + + System.out.println("server replied HTTP code: " + responseCode); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_PARTIAL) { + System.out.println("return new ConnectionImpl"); + return new ConnectionImpl(httpConn, fileURL); + } else { + throw new ConnectionException("server replied HTTP code: " + responseCode); + } + } catch (IOException e) { + throw new ConnectionException(e); + } + } + + @Override + public int getContentLength(String fileURL) throws ConnectionException { + try { + System.out.println("try to open file url: " + fileURL); + + URL url = new URL(fileURL); + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + int responseCode = httpConn.getResponseCode(); + + System.out.println("server replied HTTP code: " + responseCode); + if (responseCode == HttpURLConnection.HTTP_OK) { + System.out.println("return contentLength: " + httpConn.getContentLength()); + int contentLength = httpConn.getContentLength(); + httpConn.disconnect(); + return contentLength; + } else { + throw new ConnectionException("server replied HTTP code: " + responseCode); + } + } catch (IOException e) { + throw new ConnectionException(e); + } + } +} diff --git "a/group27/1252327158/task3_20170326/\345\217\246\344\270\200\344\270\252linkedlist\344\275\234\344\270\232\345\234\250task1\351\207\214" "b/group27/1252327158/task3_20170326/\345\217\246\344\270\200\344\270\252linkedlist\344\275\234\344\270\232\345\234\250task1\351\207\214" new file mode 100644 index 0000000000..710566766d --- /dev/null +++ "b/group27/1252327158/task3_20170326/\345\217\246\344\270\200\344\270\252linkedlist\344\275\234\344\270\232\345\234\250task1\351\207\214" @@ -0,0 +1 @@ +另一个linkedlist作业在task1里 diff --git a/group27/383117348/src/com/coderising/download/DownloadThread.java b/group27/383117348/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..739dc261a6 --- /dev/null +++ b/group27/383117348/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,61 @@ +package com.coderising.download; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.DownloadListener; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + FileDownloader fileDown; + + public DownloadThread( Connection conn, int startPos, int endPos){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ + FileOutputStream fos = null; + ByteArrayInputStream bis =null; + try { + byte[] bt = conn.read(startPos, endPos); + File file = new File("C:\\Users\\Adminstater\\Desktop\\test"+Math.ceil(Math.random()*100)+".jpg"); + if(!file.exists()){ + file.createNewFile(); + } + fos = new FileOutputStream(file); + bis = new ByteArrayInputStream(bt); + int i = 0; + byte[] copy = new byte[1024]; + while((i=bis.read(copy))!=-1){ + fos.write(copy, 0, i); + fos.flush(); + } + + DownloadListener listener = fileDown.getListener(); + listener.notifyFinished(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }finally{ + try { + fos.close(); + bis.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } + public void setFileDown(FileDownloader fileDown) { + this.fileDown = fileDown; + } + +} diff --git a/group27/383117348/src/com/coderising/download/FileDownloader.java b/group27/383117348/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..b390613073 --- /dev/null +++ b/group27/383117348/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,70 @@ +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 ; + + + 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(); + DownloadThread thread = new DownloadThread(conn,0,length-1); + thread.setFileDown(this); + thread.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/group27/383117348/src/com/coderising/download/FileDownloaderTest.java b/group27/383117348/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..6b7da40aea --- /dev/null +++ b/group27/383117348/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,55 @@ +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://pic6.huitu.com/res/20130116/84481_20130116142820494200_1.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/group27/383117348/src/com/coderising/download/api/Connection.java b/group27/383117348/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..9710e270e1 --- /dev/null +++ b/group27/383117348/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/group27/383117348/src/com/coderising/download/api/ConnectionException.java b/group27/383117348/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..8dbfe95dda --- /dev/null +++ b/group27/383117348/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group27/383117348/src/com/coderising/download/api/ConnectionManager.java b/group27/383117348/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..fb44ede457 --- /dev/null +++ b/group27/383117348/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/group27/383117348/src/com/coderising/download/api/DownloadListener.java b/group27/383117348/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..4cd0b3eab1 --- /dev/null +++ b/group27/383117348/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/group27/383117348/src/com/coderising/download/impl/ConnectionImpl.java b/group27/383117348/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..2f1cfa14a5 --- /dev/null +++ b/group27/383117348/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,71 @@ +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 com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + + private URL url; + private HttpURLConnection connection; + + public ConnectionImpl(String url) { + try { + this.url = new URL(url); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + private HttpURLConnection initConnection(){ + HttpURLConnection con = null; + try { + con = (HttpURLConnection)url.openConnection(); + con.setConnectTimeout(2000); + con.setRequestMethod("GET"); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return con; + } + @Override + public byte[] read(int startPos, int endPos) throws IOException { + connection = initConnection(); + connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); //nullPointException + InputStream input = connection.getInputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int i=0; + byte[] bt = new byte[1024]; + while((i=input.read(bt))!=-1){ + bos.write(bt,0,i); + } + return bos.toByteArray(); + } + + @Override + public int getContentLength() { + HttpURLConnection con = initConnection(); + try { + if (con.getResponseCode() == 200){ + //服务器返回内容的长度,本质就是文件的长度 + return con.getContentLength(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return 0; + } + + @Override + public void close() { + this.connection=null; + } + +} diff --git a/group27/383117348/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group27/383117348/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..f1db9d72a9 --- /dev/null +++ b/group27/383117348/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +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/group27/383117348/src/com/coding/basic/LinkedList.java b/group27/383117348/src/com/coding/basic/LinkedList.java index faeafffca6..56cead0c67 100644 --- a/group27/383117348/src/com/coding/basic/LinkedList.java +++ b/group27/383117348/src/com/coding/basic/LinkedList.java @@ -1,5 +1,6 @@ package com.coding.basic; +import java.util.Arrays; import java.util.NoSuchElementException; import org.junit.Test; @@ -266,6 +267,172 @@ private Node() { } } + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Node head = first; + Node reverse = null; + while (head != null) { + Node second = head.next; + head.next = reverse; + reverse = head; + head = second; + } + first = reverse; + } + //有问题 + @Test + public void testReverse(){ + LinkedList list = getList(); + Iterator ite = list.iterator(); + while(ite.hasNext()){ + System.out.print(ite.next()+" "); + } + list.reverse(); + Iterator it = list.iterator(); + while(it.hasNext()){ + System.out.println("----"); + System.out.print(it.next()+" "); + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + int mid = (int) Math.ceil(size/2.0); + for(int x=0;x0){ + + Node prev = getNodeByIndex(i-1); + Node next = getNodeByIndex(i+length); + for(int x=i;x101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] array = new int[list.size]; + for (int i = 0; i < array.length; i++) { + int element = (int) list.get(i); + array[i] = ((Integer) get(element)); + } + + System.out.println(Arrays.toString(array)); + + return array; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * @param list + */ + + public void subtract(LinkedList list){ + int length = list.size(); + for (int i = size - 1; i >= 0; i--) { + for (int j = 0; j < length; j++) { + if (get(i) == list.get(j)) { + remove(i); + break; + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + for (int i = size - 1; i > 0; i--) { + if (get(i) == get(i - 1)) { + remove(i); + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + for (int i = size - 1; i >= 0; i--) { + int element = ((int) get(i)); + if ((element > min) && element < max) { + remove(i); + } + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList newList = new LinkedList(); + int length = list.size(); + for (int i = 0; i < size; i++) { + for (int j = 0; j < length; j++) { + if (get(i) == list.get(j)) { + newList.add(get(i)); + break; + } + } + } + + Iterator it = newList.iterator(); + while (it.hasNext()) { + System.out.print(it.next() + " "); + } + System.out.println(); + return newList; + } /*------------------------------------------------------单元测试----------------------------------------------------*/ @@ -375,8 +542,12 @@ public void TestIterator() { System.out.println(ite.next()); } } - - public static void main(String[] args) { - java.util.LinkedList list = null; + + private LinkedList getList(){ + LinkedList list = new LinkedList(); + for (int i = 0; i < 10; i++) { + list.add(i); + } + return list; } } diff --git a/group27/513274874/homework/src/com/coding/basic/LinkedList.java b/group27/513274874/homework/src/com/coding/basic/LinkedList.java index d66be49758..1d574e8aa3 100644 --- a/group27/513274874/homework/src/com/coding/basic/LinkedList.java +++ b/group27/513274874/homework/src/com/coding/basic/LinkedList.java @@ -185,4 +185,81 @@ public void setNext(Node next) { } + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int 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){ + 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; + } + + } \ No newline at end of file diff --git a/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java b/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java index 1456314140..eca4a105e6 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java @@ -1,6 +1,9 @@ -package com.coderising.download; +package com.coding.coderising.download; -import com.coderising.download.api.Connection; +import com.coding.coderising.download.api.Connection; + +import java.io.IOException; +import java.io.RandomAccessFile; public class DownloadThread extends Thread{ @@ -8,13 +11,20 @@ public class DownloadThread extends Thread{ int startPos; int endPos; + // 将下载到的字节输出到raf中 + private RandomAccessFile raf; + public DownloadThread( Connection conn, int startPos, int endPos){ this.conn = conn; this.startPos = startPos; this.endPos = endPos; } - public void run(){ - + public void run(){ + try { + conn.read(startPos,endPos); + } catch (IOException e) { + e.printStackTrace(); + } } } diff --git a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java index f5d7999eb4..dc99e91598 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java @@ -1,9 +1,9 @@ -package com.coderising.download; +package com.coding.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.coding.coderising.download.api.Connection; +import com.coding.coderising.download.api.ConnectionException; +import com.coding.coderising.download.api.ConnectionManager; +import com.coding.coderising.download.api.DownloadListener; public class FileDownloader { diff --git a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java index 8171ee5763..8a9531530f 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java @@ -1,12 +1,12 @@ -package com.coderising.download; +package com.coding.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; +import com.coding.coderising.download.api.ConnectionManager; +import com.coding.coderising.download.api.DownloadListener; +import com.coding.coderising.download.impl.ConnectionManagerImpl; public class FileDownloaderTest { boolean downloadFinished = false; diff --git a/group27/513274874/homework/src/com/coding/coderising/download/api/Connection.java b/group27/513274874/homework/src/com/coding/coderising/download/api/Connection.java index 9710e270e1..1b00c983d6 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/api/Connection.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/api/Connection.java @@ -1,4 +1,4 @@ -package com.coderising.download.api; +package com.coding.coderising.download.api; import java.io.IOException; diff --git a/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionException.java b/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionException.java index 8dbfe95dda..e08c73bd98 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionException.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionException.java @@ -1,4 +1,4 @@ -package com.coderising.download.api; +package com.coding.coderising.download.api; public class ConnectionException extends Exception { diff --git a/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionManager.java b/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionManager.java index fb44ede457..f95561e023 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionManager.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/api/ConnectionManager.java @@ -1,4 +1,4 @@ -package com.coderising.download.api; +package com.coding.coderising.download.api; public interface ConnectionManager { /** diff --git a/group27/513274874/homework/src/com/coding/coderising/download/api/DownloadListener.java b/group27/513274874/homework/src/com/coding/coderising/download/api/DownloadListener.java index 4cd0b3eab1..32c399a204 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/api/DownloadListener.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/api/DownloadListener.java @@ -1,4 +1,4 @@ -package com.coderising.download.api; +package com.coding.coderising.download.api; public interface DownloadListener { public void notifyFinished(); diff --git a/group27/513274874/homework/src/com/coding/coderising/download/demo/DownThread.java b/group27/513274874/homework/src/com/coding/coderising/download/demo/DownThread.java new file mode 100644 index 0000000000..b675d65c9d --- /dev/null +++ b/group27/513274874/homework/src/com/coding/coderising/download/demo/DownThread.java @@ -0,0 +1,72 @@ +package com.coding.coderising.download.demo; + +import java.io.InputStream; +import java.io.RandomAccessFile; + +public class DownThread extends Thread { + + // 定义字节数组(取水的竹筒)的长度 + private final int BUFF_LEN = 32; + + // 定义下载的起始点 + private long start; + + // 定义下载的结束点 + private long end; + + // 下载资源对应的输入流 + private InputStream is; + + // 将下载到的字节输出到raf中 + private RandomAccessFile raf; + + + // 构造器,传入输入流,输出流和下载起始点、结束点 + public DownThread(long start, long end, InputStream is, RandomAccessFile raf) { + // 输出该线程负责下载的字节位置 + System.out.println(start + "---->" + end); + this.start = start; + this.end = end; + this.is = is; + this.raf = raf; + } + + @Override + public void run() { + try { + is.skip(start); + raf.seek(start); + // 定义读取输入流内容的的缓存数组(竹筒) + byte[] buff = new byte[BUFF_LEN]; + // 本线程负责下载资源的大小 + long contentLen = end - start; + // 定义最多需要读取几次就可以完成本线程的下载 + long times = contentLen / BUFF_LEN + 4; + // 实际读取的字节数 + int hasRead = 0; + for (int i = 0; i < times; i++) { + hasRead = is.read(buff); + // 如果读取的字节数小于0,则退出循环! + if (hasRead < 0) { + break; + } + raf.write(buff, 0, hasRead); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + // 使用finally块来关闭当前线程的输入流、输出流 + finally { + try { + if (is != null) { + is.close(); + } + if (raf != null) { + raf.close(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/group27/513274874/homework/src/com/coding/coderising/download/demo/MutilDown.java b/group27/513274874/homework/src/com/coding/coderising/download/demo/MutilDown.java new file mode 100644 index 0000000000..3b6cfa020d --- /dev/null +++ b/group27/513274874/homework/src/com/coding/coderising/download/demo/MutilDown.java @@ -0,0 +1,72 @@ +package com.coding.coderising.download.demo; + +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.URL; +import java.net.URLConnection; + +public class MutilDown { + + public static void main(String[] args) { + //定义几个线程去下载 + final int DOWN_THREAD_NUM = 4; + final String OUT_FILE_NAME = "down.jpg"; + InputStream[] isArr = new InputStream[DOWN_THREAD_NUM]; + RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM]; + try { + // 创建一个URL对象 + URL url = new URL("http://hiphotos.baidu.com/240728057/pic/item/6a50e38242aad8f60cf4d2b3.jpg"); + // 以此URL对象打开第一个输入流 + isArr[0] = url.openStream(); + long fileLen = getFileLength(url); + System.out.println("网络资源的大小" + fileLen); + // 以输出文件名创建第一个RandomAccessFile输出流 + //创建从中读取和向其中写入(可选)的随机存取文件流,第一个参数:文件名,第二个参数是:参数指定用以打开文件的访问模式 + //"rw"可能是可读可写, + outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw"); + // 创建一个与下载资源相同大小的空文件 + for (int i = 0; i < fileLen; i++) { + outArr[0].write(0); + } + // 每线程应该下载的字节数 + long numPerThred = fileLen / DOWN_THREAD_NUM; + // 整个下载资源整除后剩下的余数取模 + long left = fileLen % DOWN_THREAD_NUM; + for (int i = 0; i < DOWN_THREAD_NUM; i++) { + // 为每个线程打开一个输入流、一个RandomAccessFile对象, + // 让每个线程分别负责下载资源的不同部分。 + //isArr[0]和outArr[0]已经使用,从不为0开始 + if (i != 0) { + // 以URL打开多个输入流 + isArr[i] = url.openStream(); + // 以指定输出文件创建多个RandomAccessFile对象 + outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw"); + } + // 分别启动多个线程来下载网络资源 + if (i == DOWN_THREAD_NUM - 1) { + // 最后一个线程下载指定numPerThred+left个字节 + new DownThread(i * numPerThred, (i + 1) * numPerThred + + left, isArr[i], outArr[i]).start(); + } else { + // 每个线程负责下载一定的numPerThred个字节 + new DownThread(i * numPerThred, (i + 1) * numPerThred, + isArr[i], outArr[i]).start(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + // 定义获取指定网络资源的长度的方法 + public static long getFileLength(URL url) throws Exception { + long length = 0; + // 打开该URL对应的URLConnection + URLConnection con = url.openConnection(); + // 获取连接URL资源的长度 + long size = con.getContentLength(); + length = size; + return length; + } + +} \ No newline at end of file diff --git a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java index 32f03efdc7..e1f649b88b 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java @@ -1,27 +1,100 @@ -package com.coderising.download.impl; +package com.coding.coderising.download.impl; -import java.io.IOException; +import com.coding.coderising.download.api.Connection; -import com.coderising.download.api.Connection; +import java.io.*; +import java.net.URL; +import java.net.URLConnection; -public class ConnectionImpl implements Connection{ +public class ConnectionImpl implements Connection { + private URL url; - @Override - public byte[] read(int startPos, int endPos) throws IOException { - - return null; - } + // 定义字节数组(取水的竹筒)的长度 + private final int BUFF_LEN = 32; - @Override - public int getContentLength() { - - return 0; - } + // 下载资源对应的输入流 + private InputStream is; - @Override - public void close() { - - - } + ByteArrayOutputStream bos; + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + this.is = url.openStream(); + + is.skip(startPos); + // 定义读取输入流内容的的缓存数组(竹筒) + byte[] buff = new byte[BUFF_LEN]; + // 本线程负责下载资源的大小 + long contentLen = endPos - startPos; + bos = new ByteArrayOutputStream((int) contentLen); + BufferedInputStream in = new BufferedInputStream(is); + int len = 0; + while (-1 != (len = in.read(buff, 0, BUFF_LEN))) { + bos.write(buff, 0, len); + } + return bos.toByteArray(); + } +// @Override +// public byte[] read(int startPos, int endPos) throws IOException { +// raf = new RandomAccessFile("newfile.jpg", "rw"); +// this.is = url.openStream(); +// +// is.skip(startPos); +// raf.seek(startPos); +// // 定义读取输入流内容的的缓存数组(竹筒) +// byte[] buff = new byte[BUFF_LEN]; +// // 本线程负责下载资源的大小 +// long contentLen = endPos - startPos; +// ByteArrayOutputStream bos = new ByteArrayOutputStream((int) contentLen); +// // 定义最多需要读取几次就可以完成本线程的下载 +// long times = contentLen / BUFF_LEN + 4; +// // 实际读取的字节数 +// int hasRead = 0; +// for (int i = 0; i < times; i++) { +// hasRead = is.read(buff); +// // 如果读取的字节数小于0,则退出循环! +// if (hasRead < 0) { +// break; +// } +// raf.write(buff, 0, hasRead); +// } +// +// return null; +// } + + @Override + public int getContentLength() { + int length = 0; + // 打开该URL对应的URLConnection + URLConnection con = null; + try { + con = url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + // 获取连接URL资源的长度 + length = con.getContentLength(); + return length; + } + + @Override + public void close() { + try { + if (is != null) { + is.close(); + } + if (bos != null) { + bos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public ConnectionImpl(URL url) { + this.url = url; + } } diff --git a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java index 046f7c49a4..2295167f6d 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java @@ -1,15 +1,29 @@ -package com.coderising.download.impl; +package com.coding.coderising.download.impl; -import com.coderising.download.api.Connection; -import com.coderising.download.api.ConnectionException; -import com.coderising.download.api.ConnectionManager; +import com.coding.coderising.download.api.Connection; +import com.coding.coderising.download.api.ConnectionException; +import com.coding.coderising.download.api.ConnectionManager; + +import java.net.MalformedURLException; +import java.net.URL; public class ConnectionManagerImpl implements ConnectionManager { @Override public Connection open(String url) throws ConnectionException { - - return null; + + Connection connection = null; + try { + if(url == null || "".equals(url.trim())) return null; + + URL urlO = new URL(url); + connection = new ConnectionImpl(urlO); + + + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return connection; } } diff --git a/group27/815591664/2017Learning/src/com/coderising/download/DownloadThread.java b/group27/815591664/2017Learning/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..9deb365291 --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,47 @@ +package com.coderising.download; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + String threadId; + int startPos; + int endPos; + + public DownloadThread( Connection conn, String threadId, int startPos, int endPos){ + + this.conn = conn; + this.threadId = threadId; + this.startPos = startPos; + this.endPos = endPos; + + } + public void run(){ + System.out.println("线程"+threadId+"开始下载,起点为"+startPos+",终点为"+endPos); + + RandomAccessFile raf; + try { + raf = new RandomAccessFile("f:/test.jpg", "rw"); + byte[] content = conn.read(startPos, endPos); + raf.seek(startPos);//文件写入的开始位置. + raf.write(content); + System.out.println("线程"+threadId+"下载完毕!"); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } +} diff --git a/group27/815591664/2017Learning/src/com/coderising/download/FileDownloader.java b/group27/815591664/2017Learning/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..ce984d9ced --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,91 @@ +package com.coderising.download; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +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 { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + int threadCount = 3; + + + public FileDownloader(String _url) { + this.url = _url; + + + } + + public FileDownloader(String _url, int _threadCount) { + this.url = _url; + this.threadCount = _threadCount; + + } + + 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(url); + + int length = conn.getContentLength(); + System.out.println(length); + for(int i = 0;i < threadCount; i++){ + int startPos = i * (length/threadCount); + int endPos = startPos + (length/threadCount); + if(i == (threadCount-1)){ + endPos = length - 1; + } + + new DownloadThread(cm.open(url), String.valueOf(i), startPos, endPos).start(); + } + + + } catch (Exception e) { + e.printStackTrace(); + } + + + + + } + + 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/group27/815591664/2017Learning/src/com/coderising/download/FileDownloaderTest.java b/group27/815591664/2017Learning/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..ebc6978554 --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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://localhost:8080/ForDownload/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/group27/815591664/2017Learning/src/com/coderising/download/Test.java b/group27/815591664/2017Learning/src/com/coderising/download/Test.java new file mode 100644 index 0000000000..994a14b989 --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/Test.java @@ -0,0 +1,172 @@ +package com.coderising.download; + +import java.io.File; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * 多线程下载 和 断点续传 + * @author 杨斌. + * + */ +public class Test { + +// private String path = "http://mpge.5nd.com/2016/2016-11-15/74847/1.mp3"; //下载路径 + private String path = "http://localhost:8080/ForDownload/test.jpg"; + private String targetFilePath="/"; //下载文件存放目录 + private int threadCount = 3; //线程数量 + + /** + * 构造方法 + * @param path 要下载文件的网络路径 + * @param targetFilePath 保存下载文件的目录 + * @param threadCount 开启的线程数量,默认为 3 + */ + public Test(String path, String targetFilePath, int threadCount) { + this.path = path; + this.targetFilePath = targetFilePath; + this.threadCount = threadCount; + } + public Test() { + + } + + /** + * 下载文件 + */ + public void download() throws Exception{ + //连接资源 + URL url = new URL(path); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(10000); + + int code = connection.getResponseCode(); + if(code == 200){ + //获取资源大小 + int connectionLength = connection.getContentLength(); + System.out.println(connectionLength); + //在本地创建一个与资源同样大小的文件来占位 + /*RandomAccessFile randomAccessFile = new RandomAccessFile(new File(targetFilePath,getFileName(url)), "rw"); + randomAccessFile.setLength(connectionLength);*/ + /* + * 将下载任务分配给每个线程 + */ + int blockSize = connectionLength/threadCount;//计算每个线程理论上下载的数量. + for(int threadId = 0; threadId < threadCount; threadId++){//为每个线程分配任务 + int startIndex = threadId * blockSize; //线程开始下载的位置 + int endIndex = (threadId+1) * blockSize -1; //线程结束下载的位置 + if(threadId == (threadCount - 1)){ //如果是最后一个线程,将剩下的文件全部交给这个线程完成 + endIndex = connectionLength - 1; + } + + new DownloadThread(threadId, startIndex, endIndex).start();//开启线程下载 + + } +// randomAccessFile.close(); + } + + } + + //下载的线程 + private class DownloadThread extends Thread{ + + private int threadId; + private int startIndex; + private int endIndex; + + public DownloadThread(int threadId, int startIndex, int endIndex) { + this.threadId = threadId; + this.startIndex = startIndex; + this.endIndex = endIndex; + } + + @Override + public void run() { + System.out.println("线程"+ threadId + "开始下载"); + try { + //分段请求网络连接,分段将文件保存到本地. + URL url = new URL(path); + + //加载下载位置的文件 + File downThreadFile = new File(targetFilePath,"downThread_" + threadId+".dt"); + RandomAccessFile downThreadStream = null; + if(downThreadFile.exists()){//如果文件存在 + downThreadStream = new RandomAccessFile(downThreadFile,"rwd"); + String startIndex_str = downThreadStream.readLine(); + this.startIndex = Integer.parseInt(startIndex_str);//设置下载起点 + + }else{ + downThreadStream = new RandomAccessFile(downThreadFile,"rwd"); + } + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(10000); + + //设置分段下载的头信息。 Range:做分段数据请求用的。格式: Range bytes=0-1024 或者 bytes:0-1024 + connection.setRequestProperty("Range", "bytes="+ startIndex + "-" + endIndex); + + System.out.println("线程_"+threadId + "的下载起点是 " + startIndex + " 下载终点是: " + endIndex); + + if(connection.getResponseCode() == 206){//200:请求全部资源成功, 206代表部分资源请求成功 + InputStream inputStream = connection.getInputStream();//获取流 + RandomAccessFile randomAccessFile = new RandomAccessFile( + new File(targetFilePath,getFileName(url)), "rw");//获取前面已创建的文件. + randomAccessFile.seek(startIndex);//文件写入的开始位置. + + + /* + * 将网络流中的文件写入本地 + */ + byte[] buffer = new byte[1024]; + int length = -1; + int total = 0;//记录本次下载文件的大小 + while((length = inputStream.read(buffer)) > 0){ + randomAccessFile.write(buffer, 0, length); + total += length; + /* + * 将当前现在到的位置保存到文件中 + */ + downThreadStream.seek(0); + downThreadStream.write((startIndex + total + "").getBytes("UTF-8")); + } + + downThreadStream.close(); + inputStream.close(); + randomAccessFile.close(); + cleanTemp(downThreadFile);//删除临时文件 + System.out.println("线程"+ threadId + "下载完毕"); + }else{ + System.out.println("响应码是" +connection.getResponseCode() + ". 服务器不支持多线程下载"); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + } + + //删除线程产生的临时文件 + private synchronized void cleanTemp(File file){ + file.delete(); + } + + //获取下载文件的名称 + private String getFileName(URL url){ + String filename = url.getFile(); + return filename.substring(filename.lastIndexOf("/")+1); + } + + public static void main(String[] args) { + try { + new Test().download(); + + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group27/815591664/2017Learning/src/com/coderising/download/api/Connection.java b/group27/815591664/2017Learning/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..7a8c9e7600 --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/api/Connection.java @@ -0,0 +1,25 @@ +package com.coderising.download.api; + +import java.io.IOException; +import java.net.HttpURLConnection; + +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/group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionException.java b/group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionManager.java b/group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group27/815591664/2017Learning/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/group27/815591664/2017Learning/src/com/coderising/download/api/DownloadListener.java b/group27/815591664/2017Learning/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group27/815591664/2017Learning/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/group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionImpl.java b/group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..2d1053ebae --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,44 @@ +package com.coderising.download.impl; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + + private HttpURLConnection conn = null; + + public ConnectionImpl(HttpURLConnection conn) { + super(); + this.conn = conn; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + conn.setRequestProperty("Range", "bytes="+ startPos + "-" + endPos); + InputStream is = conn.getInputStream(); + byte[] buffer = new byte[endPos - startPos + 1]; + is.read(buffer, 0, endPos - startPos + 1); + + return buffer; + + } + + @Override + public int getContentLength(){ + return conn.getContentLength(); + } + + @Override + public void close() { + + if(conn != null){ + conn.disconnect(); + } + } + +} diff --git a/group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..69817bd783 --- /dev/null +++ b/group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,47 @@ +package com.coderising.download.impl; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; +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 { + + try { + URL urlObj = new URL(url); + HttpURLConnection conn = (HttpURLConnection)urlObj.openConnection(); + //超时 + conn.setConnectTimeout(3*1000); + //conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + conn.setRequestMethod("GET"); + return new ConnectionImpl(conn); + } catch (Exception e) { + throw new ConnectionException(); + } + + } + + public static void main(String[] args) throws ConnectionException, IOException { + ConnectionManager cm = new ConnectionManagerImpl(); + Connection conn = cm.open("http://localhost:8080/ForDownload/test.jpg"); + + System.out.println(conn.getContentLength()); + + byte[] content = conn.read(0, conn.getContentLength()-1); + OutputStream os = new FileOutputStream("d:test.jpg"); + os.write(content); + os.flush(); + + conn.close(); + os.close(); + } + +} diff --git a/group27/815591664/2017Learning/src/com/coding/basic/LinkedList.java b/group27/815591664/2017Learning/src/com/coding/basic/LinkedList.java index 6f2fbf1f5b..abb912f644 100644 --- a/group27/815591664/2017Learning/src/com/coding/basic/LinkedList.java +++ b/group27/815591664/2017Learning/src/com/coding/basic/LinkedList.java @@ -3,7 +3,6 @@ public class LinkedList implements List { private Node head; - private Node tail; private int size; @@ -11,100 +10,90 @@ public void add(Object o){ this.addLast(o); } - public void add(int index , Object o) throws Exception{ + public void add(int index , Object o){ + if(index<0 || index>size){ + throw new IndexOutOfBoundsException(); + } if(index==0){ this.addFirst(o); + size++; return; - }else if(index==size-1){ + }else if(index==size){ this.addLast(o); + size++; return; - }else{ - - - Node curNode = this.getNode(index); - Node pre = curNode.previous; -// Node next = curNode.next; - // - Node newNode = new Node(o, pre, curNode); - curNode.previous = newNode; - pre.next = newNode; } + Node preNode = this.getNode(index-1); + Node curNode = this.getNode(index); + Node newNode = new Node(o, curNode); + preNode.next = newNode; + + size++; } - private Node getNode(int index) throws Exception{ - if(index>=size){ - throw new Exception("±곬"); + + private Node getNode(int index){ + if(index <0 || index>=size){ + throw new IndexOutOfBoundsException(); } if(index ==0){ return head; - }else if(index==size-1){ - return tail; - - }else{ - Node temp = head; - for(int i =1;i<=index;i++){ - temp = temp.next; - } - return temp; } + Node curNode = head; + for(int i=1;i<=index;i++){ + curNode = curNode.next; + } + return curNode; } - public Object get(int index) throws Exception{ - if(index>=size){ - throw new Exception("±곬"); + + public Object get(int index){ + if(index<0 || index>=size){ + throw new IndexOutOfBoundsException(); } - if(index ==0){ - return head.data; - }else if(index==size-1){ - return tail.data; - - }else{ - Node temp = head; - for(int i =1;i<=index;i++){ - temp = temp.next; - } - return temp.data; + + Node temp = head; + for(int i =1;i<=index;i++){ + temp = temp.next; } + return temp.data; } - public Object remove(int index) throws Exception{ - if(index>=size){ - throw new Exception("±곬"); + public Object remove(int index){ + if(index<0 || index>=size){ + throw new IndexOutOfBoundsException(); } Object o = null; if(size == 1){ o = head.data; + size--; + return o; + } + if(index==0){ + o = head.data; + Node afterHead = head.next; + head = afterHead; + + }else if(index==size-1){ + Node preTail = getNode(index-1); + Node tail = preTail.next; + o = tail.data; + preTail.next = null; }else{ - if(index==0){ - - Node afterHead = head.next; - afterHead.previous = null; - head = afterHead; - o = head.data; - - }else if(index == size-1){ - Node beforeTail = tail.previous; - beforeTail.next = null; - tail = beforeTail; - o = tail.data; - }else{ - Node curNode = this.getNode(index); - Node pre = curNode.previous; - Node next = curNode.next; - //мڶϿָ - Node temp = new Node(next.data, pre, next.next); - pre.next = temp; - next = temp; - o = curNode.data; - - } + Node preCur = getNode(index-1); + Node cur = preCur.next; + Node nextCur = cur.next; + o = cur.data; + preCur.next = nextCur; + + } + size--; + return o; - } - size--; - return o; + } @@ -114,39 +103,39 @@ public int size(){ } public void addFirst(Object o){ - Node node = new Node(o, null, head); + Node node = new Node(o,null); if(head == null){ head = node; - tail = node; - }else{ - head.previous = node; - head = node; + size++; + return; } + head = new Node(o, head); size++; } public void addLast(Object o){ - //½ڵpreviousָָtail - Node curNode = new Node(o, tail, null); - if(tail==null){ - //ǰΪʱýڵͷβΪýڵ - head = curNode; - tail = curNode; - }else{ - //Ϊʱһڵnextָָ¼Ľڵ㼴 - tail.next = curNode; - //¼ڵΪtail - tail = curNode; - + //½ڵnextָָtail + Node add = new Node(o, null); + if(head==null){ + head = add; + size++; + return; + } + Node curNode = head; + while(curNode.next != null){ + curNode = curNode.next; } - size++; + curNode.next = add; + size++; } - public Object removeFirst() throws Exception{ + + + public Object removeFirst(){ return this.remove(0); } - public Object removeLast() throws Exception{ + public Object removeLast(){ return this.remove(size-1); } @@ -186,7 +175,9 @@ public String toString() { } } - sb.deleteCharAt(sb.lastIndexOf(",")); + if(sb.indexOf(",") != -1){ + sb.deleteCharAt(sb.lastIndexOf(",")); + } sb.append("]"); return sb.toString(); @@ -199,12 +190,10 @@ public String toString() { private static class Node{ private Object data; - private Node previous; private Node next; - public Node(Object data, Node previous, Node next) { + public Node(Object data, Node next) { super(); this.data = data; - this.previous = previous; this.next = next; } @@ -228,9 +217,225 @@ public static void main(String[] args) throws Exception { ll.add(4); System.out.println(ll); - Iterator itr = ll.iterator(); + + ll.reverse(); + System.out.println(ll); + /*System.out.println(ll.get(0)); + System.out.println(ll.get(1)); + System.out.println(ll.get(2));*/ + + LinkedList ll2 = new LinkedList(); + ll2.add(1); +// ll2.add(1); + ll2.add(2); +// ll2.add(3); + ll2.add(3); +// ll2.add(4); + ll2.add(4); + ll2.add(5); +// ll2.removeFirstHalf(); +// ll2.remove(2,3); +// ll2.removeDuplicateValues(); + + System.out.println(ll2); + +// ll2.removeRange(2, 6); +// ll2.remove(3); + System.out.println(ll2); + + LinkedList ll3 = new LinkedList(); + ll3.add(2); + ll3.add(4); + ll2.subtract(ll3); + System.out.println(ll2); + + + + + + } + + + /** + * Ѹ + * Ϊ 3->7->10 , úΪ 10->7->3 + */ + public void reverse(){ + LinkedList temp = new LinkedList(); + for(int i = size - 1;i >= 0; i--){ + temp.add(this.get(i)); + } + System.out.println("---"+temp.toString()+"---"); + //ԭ + this.clear(); + + System.out.println("---"+this.toString()+"---"); + for(int i = 0; i < temp.size();i++){ + Object o = temp.get(i); + this.add(o); + } + + } + + /** + * ɾһǰ벿 + * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + + */ + public void removeFirstHalf(){ + if(this.size() == 0){ + return; + } + int temp = this.size(); + for(int i = 1; i <= temp/2; i++){ + this.removeFirst(); + } + + + } + + public void clear(){ + + Iterator itr = this.iterator(); while(itr.hasNext()){ - System.out.println(itr.next()); + this.removeFirst(); + } + this.head = null; + } + + /** + * ӵiԪؿʼ ɾlength Ԫ עi0ʼ + * @param i + * @param length + */ + public void remove(int i, int length){ + + for(int j = 0;j < length; j++){ + this.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){ + int[] result = new int[list.size()]; + for(int i = 0; i min && countForMin == 0){ + indexMin = i; + countForMin++; + } + if(eleBack < max && countForMax == 0){ + indexMax = this.size()-1-i; + countForMax++; + } + } + + if(indexMin != -1 && indexMax != -1){ + for(int i = indexMin; i <= indexMax; i++){ + this.remove(indexMin); + } + + } + + } + + /** + * 赱ǰͲlistָԪֵУͬһеԪֵͬ + * ҪCԪΪǰlistԪصĽұCеԪֵ + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList result = new LinkedList(); + for(int i = 0; i < this.size(); i++){ + Integer temp1 = (Integer)this.get(i); + for(int j = 0; j < list.size(); j++){ + Integer temp2 = (Integer)list.get(j); + if(temp1 == temp2){ + result.add(temp2); + } + + } } + return result; } } diff --git a/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java b/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java index a4f2c14606..24b9d8b155 100644 --- a/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java +++ b/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java @@ -1,10 +1,6 @@ package com.coding.basic.linklist; -/** - * 用双向链表实现LRU算法 - * @author liuxin - * - */ + public class LRUPageFrame { private static class Node { @@ -19,13 +15,13 @@ private static class Node { private int capacity; - + private int currentSize; private Node first;// 链表头 private Node last;// 链表尾 public LRUPageFrame(int capacity) { - + this.currentSize = 0; this.capacity = capacity; } @@ -38,11 +34,117 @@ public LRUPageFrame(int capacity) { */ public void access(int pageNum) { + Node node = find(pageNum); + //在该队列中存在, 则提到队列头 + if (node != null) { + + moveExistingNodeToHead(node); + + } else{ + + node = new Node(); + node.pageNum = pageNum; + + // 缓存容器是否已经超过大小. + if (currentSize >= capacity) { + removeLast(); + + } + + addNewNodetoHead(node); + + + + + } + } + private void addNewNodetoHead(Node node) { + + if(isEmpty()){ + + node.prev = null; + node.next = null; + first = node; + last = node; + + } else{ + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + this.currentSize ++; + } + + private Node find(int data){ + + Node node = first; + while(node != null){ + if(node.pageNum == data){ + return node; + } + node = node.next; + } + return null; + } + + + + /** + * 删除链表尾部节点 表示 删除最少使用的缓存对象 + */ + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev; + this.currentSize --; + } + + /** + * 移动到链表头,表示这个节点是最新使用过的 + * + * @param node + */ + private void moveExistingNodeToHead(Node node) { + + if (node == first) { + + return; + } + else if(node == last){ + //当前节点是链表尾, 需要放到链表头 + Node prevNode = node.prev; + prevNode.next = null; + last.prev = null; + last = prevNode; + + } else{ + //node 在链表的中间, 把node 的前后节点连接起来 + Node prevNode = node.prev; + prevNode.next = node.next; + + Node nextNode = node.next; + nextNode.prev = prevNode; + + + } + + node.prev = null; + node.next = first; + first.prev = node; + first = node; + + } + private boolean isEmpty(){ + return (first == null) && (last == null); + } + public String toString(){ StringBuilder buffer = new StringBuilder(); Node node = first; @@ -57,4 +159,6 @@ public String toString(){ return buffer.toString(); } + + } diff --git a/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java b/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java index 67cf36067b..7fd72fc2b4 100644 --- a/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java +++ b/liuxin/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -26,6 +26,9 @@ public void testAccess() { Assert.assertEquals("0,3,2", frame.toString()); frame.access(4); Assert.assertEquals("4,0,3", frame.toString()); + frame.access(5); + Assert.assertEquals("5,4,0", frame.toString()); + } } diff --git a/liuxin/data-structure/src/com/coding/basic/stack/Stack.java b/liuxin/data-structure/src/com/coding/basic/stack/Stack.java new file mode 100644 index 0000000000..4f4b9af52e --- /dev/null +++ b/liuxin/data-structure/src/com/coding/basic/stack/Stack.java @@ -0,0 +1,24 @@ +package com.coding.basic.stack; + +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/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java new file mode 100644 index 0000000000..434d991447 --- /dev/null +++ b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,45 @@ +package com.coding.basic.stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + return null; + } + /** + * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz + * 使用堆栈检查字符串s中的括号是不是成对出现的。 + * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true + * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false; + * @param s + * @return + */ + public static boolean isValidPairs(String s){ + return false; + } + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java b/liuxin/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..faae056835 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.coderising.jvm.clz; + +public class AccessFlag { + private int flagValue; + + public AccessFlag(int value) { + this.flagValue = value; + } + + public int getFlagValue() { + return flagValue; + } + + public void setFlagValue(int flag) { + this.flagValue = flag; + } + + public boolean isPublicClass(){ + return (this.flagValue & 0x0001) != 0; + } + public boolean isFinalClass(){ + return (this.flagValue & 0x0010) != 0; + } + +} \ No newline at end of file diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..650ca8375d --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,75 @@ +package com.coderising.jvm.clz; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + + + public ClassIndex getClzIndex() { + return clzIndex; + } + public AccessFlag getAccessFlag() { + return accessFlag; + } + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + + + public ConstantPool getConstantPool() { + return pool; + } + public int getMinorVersion() { + return minorVersion; + } + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + public int getMajorVersion() { + return majorVersion; + } + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + public void setConstPool(ConstantPool pool) { + this.pool = pool; + + } + public void setClassIndex(ClassIndex clzIndex) { + this.clzIndex = clzIndex; + } + + + + + public void print(){ + + if(this.accessFlag.isPublicClass()){ + System.out.println("Access flag : public "); + } + System.out.println("Class Name:"+ getClassName()); + + System.out.println("Super Class Name:"+ getSuperClassName()); + + + } + + private String getClassName(){ + int thisClassIndex = this.clzIndex.getThisClassIndex(); + ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); + return thisClass.getClassName(); + } + private String getSuperClassName(){ + ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); + return superClass.getClassName(); + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..e424f284b3 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.clz; + +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + + public int getThisClassIndex() { + return thisClassIndex; + } + public void setThisClassIndex(int thisClassIndex) { + this.thisClassIndex = thisClassIndex; + } + public int getSuperClassIndex() { + return superClassIndex; + } + public void setSuperClassIndex(int superClassIndex) { + this.superClassIndex = superClassIndex; + } +} \ No newline at end of file diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..aea9048ea4 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.constant; + +public class ClassInfo extends ConstantInfo { + private int type = ConstantInfo.CLASS_INFO; + private int utf8Index ; + public ClassInfo(ConstantPool pool) { + super(pool); + } + public int getUtf8Index() { + return utf8Index; + } + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..466b072244 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +public abstract class ConstantInfo { + public static final int UTF8_INFO = 1; + public static final int FLOAT_INFO = 4; + public static final int CLASS_INFO = 7; + public static final int STRING_INFO = 8; + public static final int FIELD_INFO = 9; + public static final int METHOD_INFO = 10; + public static final int NAME_AND_TYPE_INFO = 12; + protected ConstantPool constantPool; + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + public abstract int getType(); + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..86c0445695 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.coderising.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +public class ConstantPool { + + private List constantInfos = new ArrayList(); + + + public ConstantPool(){ + + } + public void addConstantInfo(ConstantInfo info){ + + this.constantInfos.add(info); + + } + + public ConstantInfo getConstantInfo(int index){ + return this.constantInfos.get(index); + } + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfos.get(index)).getValue(); + } + public Object getSize() { + return this.constantInfos.size() -1; + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..65475e194c --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coderising.jvm.constant; + +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.FIELD_INFO; + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool pool) { + super(pool); + } + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + + return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]"; + } + + public String getClassName(){ + + ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex()); + + UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index()); + + return utf8Info.getValue(); + + } + + public String getFieldName(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getFieldType(){ + NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..7f05870020 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coderising.jvm.constant; + +public class MethodRefInfo extends ConstantInfo { + + private int type = ConstantInfo.METHOD_INFO; + + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getClassInfoIndex() { + return classInfoIndex; + } + public void setClassInfoIndex(int classInfoIndex) { + this.classInfoIndex = classInfoIndex; + } + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + public void setNameAndTypeIndex(int nameAndTypeIndex) { + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public String toString(){ + + return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ; + } + public String getClassName(){ + ConstantPool pool = this.getConstantPool(); + ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex()); + return clzInfo.getClassName(); + } + + public String getMethodName(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getName(); + } + + public String getParamAndReturnType(){ + ConstantPool pool = this.getConstantPool(); + NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); + return typeInfo.getTypeInfo(); + } + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..402f9dec86 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coderising.jvm.constant; + +public class NameAndTypeInfo extends ConstantInfo{ + public int type = ConstantInfo.NAME_AND_TYPE_INFO; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + public int getIndex1() { + return index1; + } + public void setIndex1(int index1) { + this.index1 = index1; + } + public int getIndex2() { + return index2; + } + public void setIndex2(int index2) { + this.index2 = index2; + } + public int getType() { + return type; + } + + + public String getName(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1); + return utf8Info1.getValue(); + } + + public String getTypeInfo(){ + ConstantPool pool = this.getConstantPool(); + UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2); + return utf8Info2.getValue(); + } + + public String toString(){ + return "(" + getName() + "," + getTypeInfo()+")"; + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..936736016f --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..f1f8eb4ed4 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coderising.jvm.constant; + +public class StringInfo extends ConstantInfo{ + private int type = ConstantInfo.STRING_INFO; + private int index; + public StringInfo(ConstantPool pool) { + super(pool); + } + + public int getType() { + return type; + } + + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + + + public String toString(){ + return this.getConstantPool().getUTF8String(index); + } + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java b/liuxin/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..5cac9f04f7 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coderising.jvm.constant; + +public class UTF8Info extends ConstantInfo{ + private int type = ConstantInfo.UTF8_INFO; + private int length ; + private String value; + public UTF8Info(ConstantPool pool) { + super(pool); + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getType() { + return type; + } + @Override + public String toString() { + return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]"; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..9c9fac2839 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,5 @@ +package com.coderising.jvm.loader; + +public class ByteCodeIterator { + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java index 86d4619407..9ff27b16cf 100644 --- a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -1,8 +1,20 @@ package com.coderising.jvm.loader; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import com.coderising.jvm.clz.ClassFile; + + + public class ClassFileLoader { @@ -11,24 +23,118 @@ public class ClassFileLoader { public byte[] readBinaryCode(String className) { - return null; + className = className.replace('.', File.separatorChar) +".class"; + + for(String path : this.clzPaths){ + + String clzFileName = path + File.separatorChar + className; + byte[] codes = loadClassFile(clzFileName); + if(codes != null){ + return codes; + } + } + + return null; + } + private byte[] loadClassFile(String clzFileName) { + + File f = new File(clzFileName); + + try { + + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public void addClassPath(String path) { + if(this.clzPaths.contains(path)){ + return; + } + + this.clzPaths.add(path); } public String getClassPath(){ - return null; + return StringUtils.join(this.clzPaths,";"); } + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + + // ------------------------------backup------------------------ + public String getClassPath_V1(){ + + StringBuffer buffer = new StringBuffer(); + for(int i=0;i", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(10); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(11); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); + Assert.assertEquals(3, methodRef.getClassInfoIndex()); + Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); + Assert.assertEquals(9, nameAndType.getIndex1()); + Assert.assertEquals(14, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); + Assert.assertEquals(1, methodRef.getClassInfoIndex()); + Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); + Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); + } + } + @Test + public void testClassIndex(){ + + ClassIndex clzIndex = clzFile.getClzIndex(); + ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); + ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); + + + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); + Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); + } + + } diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/util/Util.java b/liuxin/mini-jvm/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..0c4cc8c57c --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.coderising.jvm.util; + +public class Util { + public static int byteToInt(byte[] codes){ + String s1 = byteToHexString(codes); + return Integer.valueOf(s1, 16).intValue(); + } + + + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i