From 63c9429bb38a7c1141c32791d4708890e176e770 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Wed, 5 Apr 2017 16:59:15 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E5=91=A8=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../week1/homework/arrayList/ArrayList.java | 107 +++++++++++++++ .../binaryNodeTree/BinaryTreeNode.java | 58 ++++++++ .../week1/homework/linkedList/LinkedList.java | 129 ++++++++++++++++++ .../main/java/week1/homework/list/List.java | 12 ++ .../main/java/week1/homework/queue/Queue.java | 72 ++++++++++ .../main/java/week1/homework/stack/Stack.java | 43 ++++++ .../java/week2/homework/array/ArrayUtil.java | 97 +++++++++++++ .../src/test/java/ArrayListTest.java | 67 +++++++++ .../src/test/java/BinaryNodeTreeTest.java | 27 ++++ .../src/test/java/LinkedListTest.java | 60 ++++++++ .../learning2017/src/test/java/QueueTest.java | 48 +++++++ .../learning2017/src/test/java/StackTest.java | 47 +++++++ 12 files changed, 767 insertions(+) create mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java create mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java create mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java create mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/list/List.java create mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java create mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java create mode 100644 group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java create mode 100644 group24/75939388/learning2017/src/test/java/ArrayListTest.java create mode 100644 group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java create mode 100644 group24/75939388/learning2017/src/test/java/LinkedListTest.java create mode 100644 group24/75939388/learning2017/src/test/java/QueueTest.java create mode 100644 group24/75939388/learning2017/src/test/java/StackTest.java diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java b/group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java new file mode 100644 index 0000000000..8d0b2c5d8a --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java @@ -0,0 +1,107 @@ +package week1.homework.arrayList; + +import week1.homework.list.List; + +/** + * Created by macvi on 2017/4/2. + */ +public class ArrayList implements List { + private int size = 10; + //每次扩容的长度,默认为10 + private int extendSize = 10; + + private Object[] data = new Object[size]; + + public ArrayList(Object o) { + this.add(o); + } + + public ArrayList(){} + + public void add(Object o) { + if (this.size() == this.size) { + this.size += extendSize; + Object[] newData = new Object[this.size]; + System.arraycopy(this.data, 0, newData, 0, this.data.length); + this.data = newData; + } + + for (int i = 0; i < this.data.length; i++) { + if (data[i] == null) { + data[i] = o; + break; + } else continue; + } + } + + public void add(int index, Object o) { + if (index > this.size() || index < 0) { + throw new IndexOutOfBoundsException(); + } + + if(this.size() == this.size){ + this.size += extendSize; + } + + Object[] newData = new Object[this.size]; + + System.arraycopy(this.data, 0, newData, 0, index); + newData[index] = o; + System.arraycopy(this.data, index, newData, index + 1, this.size() - index); + + this.data = newData; + } + + public Object get(int index) { + if(index > this.size() || index < 0){ + throw new IndexOutOfBoundsException(); + } + for(int i = 0; i < this.size(); i ++){ + if(index == i){ + return this.data[i]; + } + } + + return null; + } + + public Object remove(int index) { + if(index > this.size() || index < 0){ + throw new IndexOutOfBoundsException(); + } + + Object[] newData = new Object[this.size]; + Object removed = this.get(index); + + System.arraycopy(this.data, 0, newData, 0, index); + System.arraycopy(this.data, index + 1, newData, index, this.size() - index); + this.data = newData; + return removed; + } + + public int size() { + int size = 0; + for(Object obj : this.data){ + if(obj != null){ + size += 1; + } + } + + return size; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + for(Object obj : data){ + if(obj != null){ + sb.append(obj.toString()).append(","); + }else { +// sb.append("null,"); + continue; + } + } + + return sb.toString(); + } +} diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java b/group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java new file mode 100644 index 0000000000..a7da1d42da --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java @@ -0,0 +1,58 @@ +package week1.homework.binaryNodeTree; + +/** + * Created by macvi on 2017/4/4. + */ +public class BinaryTreeNode { + private int data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + private BinaryTreeNode(){} + + public BinaryTreeNode(int data){ + this.data = data; + this.left = null; + this.right = null; + } + + public void setData(int data){ + BinaryTreeNode node = new BinaryTreeNode(data); + if(compareTo(data)){ + if(this.left == null){ + this.left = node; + }else{ + this.left.setData(data); + } + }else{ + if(this.right == null){ + this.right = node; + }else{ + this.right.setData(data); + } + } + } + + public int getData(){ + return data; + } + + private boolean compareTo(int d) { + System.out.println("data=" + this.data + ", d=" + d); + return this.data > d; + } + + private StringBuffer dataStr = new StringBuffer(); + private int index = 0; +// public String toString(BinaryTreeNode node) { +// while (node.left != null || node.right != null){ +// dataStr.append(index + "层,数据=").append(node.data).append("|"); +// if(node.left != null){ +// dataStr.append(node.left.data) +// } +// index ++; +// } +// +// return dataStr.toString(); +// } +} diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java b/group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java new file mode 100644 index 0000000000..c912377e62 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java @@ -0,0 +1,129 @@ +package week1.homework.linkedList; + +import week1.homework.list.List; + +/** + * Created by macvi on 2017/4/3. + */ +public class LinkedList implements List { + private Node head; + + public LinkedList() { + this.head = new Node(); + } + + public void add(Object o) { + if (this.head.data == null) { + this.head = new Node(o, null); + } else { + Node temp = this.head; + while (temp.next != null) { + temp = temp.next; + } + temp.next = new Node(o, null); + } + } + + public void add(int index, Object o) { + if (index > this.size() || index < 0) { + throw new IndexOutOfBoundsException(); + } + + if(index == 0){ + Node newNode = new Node(o, this.head); + this.head = newNode; + return; + } + + if(index == this.size()){ + this.add(o); + return; + } + + Node before = getNode(index - 1); + Node next = getNode(index); + Node newNode = new Node(o, next); + before.next = newNode; + + } + + private Node getNode(int index) { + int i = 0; + Node temp = this.head; + while (temp.data != null) { + if (index == i) { + return temp; + } + + if (temp.next != null) { + temp = temp.next; + } else break; + + i++; + } + + return null; + } + + public Object get(int index) { + if (index > this.size() || index < 0) { + throw new IndexOutOfBoundsException(); + } + + return this.getNode(index).data; + } + + public Object remove(int index) { + if(index > this.size() || index < 0){ + throw new IndexOutOfBoundsException(); + } + + Object removed = get(index); + + Node before = getNode(index - 1); + Node next = getNode(index + 1); + before.next = next; + + return removed; + } + + public int size() { + int size = 0; + Node temp = this.head; + while (temp.data != null) { + size++; + if (temp.next != null) { + temp = temp.next; + } else break; + } + + return size; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + Node temp = this.head; + while (temp.data != null) { + sb.append(temp.data.toString()).append(","); + if (temp.next != null) { + temp = temp.next; + } else break; + } + + return sb.toString(); + } + + private static class Node { + Object data; + Node next; + + public Node() {} + + public Node(Object obj, Node next) { + this.data = obj; + this.next = next; + } + + } + +} diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/list/List.java b/group24/75939388/learning2017/src/main/java/week1/homework/list/List.java new file mode 100644 index 0000000000..a33edd34fc --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week1/homework/list/List.java @@ -0,0 +1,12 @@ +package week1.homework.list; + +/** + * Created by macvi on 2017/4/2. + */ +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/group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java b/group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java new file mode 100644 index 0000000000..3f6e3b94df --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java @@ -0,0 +1,72 @@ +package week1.homework.queue; + +/** + * Created by macvi on 2017/4/4. + */ +public class Queue { + private Object[] data; + + private int size = 10; + + private int extendedSize = 10; + + public Queue(){ + this.data = new Object[size]; + } + + public Queue(Object o){ + this.data = new Object[size]; + data[0] = o; + } + + public void enQueue(Object o){ + //被添加的位置 + int index = this.size(); + if(this.size() == this.size){ + this.size += extendedSize; + Object[] newData = new Object[this.size]; + System.arraycopy(this.data, 0, newData, 0, index); + newData[index] = o; + this.data = newData; + }else{ + this.data[index] = o; + } + } + + public Object deQueue(){ + Object[] newData = new Object[this.size]; + Object d = this.data[0]; + System.arraycopy(this.data, 1, newData, 0, this.size - 1); + this.data = newData; + + return d; + } + + public Object peek(){ + return this.data[0]; + } + + public boolean isEmpty(){ + return peek() == null; + } + + public int size(){ + int size = 0; + for(Object obj : this.data){ + size += obj == null ? 0 : 1; + } + + return size; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + for(Object obj : this.data){ + if(obj != null){ + sb.append(obj.toString()).append(","); + }else break; + } + return sb.toString(); + } +} diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java b/group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java new file mode 100644 index 0000000000..c451c28228 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java @@ -0,0 +1,43 @@ +package week1.homework.stack; + +import week1.homework.arrayList.ArrayList; + +/** + * Created by macvi on 2017/4/4. + */ +public class Stack { + + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + this.elementData.add(o); + } + + public Object pop(){ + int index = elementData.size() - 1; + Object obj = elementData.remove(index); + + return obj; + } + + public Object peek(){ + int index = elementData.size() - 1; + return elementData.get(index); + } + public boolean isEmpty(){ + return peek() == null; + } + public int size(){ + return elementData.size(); + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + for(int i = this.size() - 1; i >= 0; i--){ + sb.append(elementData.get(i).toString()).append(","); + } + + return sb.toString(); + } +} diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java new file mode 100644 index 0000000000..1c619a402e --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java @@ -0,0 +1,97 @@ +package week2.homework.array; + +/** + * @author : 温友朝 + * @date : 2017/4/5 + */ +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/group24/75939388/learning2017/src/test/java/ArrayListTest.java b/group24/75939388/learning2017/src/test/java/ArrayListTest.java new file mode 100644 index 0000000000..a445b1eb02 --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/ArrayListTest.java @@ -0,0 +1,67 @@ +import org.junit.Test; +import week1.homework.arrayList.ArrayList; + +/** + * Created by macvi on 2017/4/2. + */ +public class ArrayListTest { + + @Test + public void TestAdd(){ + ArrayList al = new ArrayList(); + for(int i = 0; i < 32; i++){ + al.add(i + ""); + } + + System.out.println("ArrayList.content-->" + al.toString()); + } + + + @Test + public void testIndexAdd(){ + ArrayList al = new ArrayList(); + for(int i = 0; i < 17; i ++){ + al.add(i + ""); + } + + al.add(3, "xxoo"); + al.add(11, "abcd"); + al.add(0, "efgh"); + al.add(al.size(), "ijkl"); + + System.out.println("al.toString-->" + al.toString()); + System.out.println("size-->" + al.size()); + } + + @Test + public void testGet(){ + ArrayList al = new ArrayList(); + for(int i = 0; i < 18; i ++){ + al.add(i + "zxcd"); + } + + System.out.println("get-->" + al.get(13)); + } + + @Test + public void testRemove(){ + ArrayList al = new ArrayList(); + for(int i = 0; i < 18; i ++){ + al.add(i + ""); + } + System.out.println("size1-->" + al.size()); + System.out.println("al.toString1-->" + al.toString()); + String re = (String)al.remove(12); + System.out.println("remove index=12 :"); + System.out.println("re-->" + re); + System.out.println("size2-->" + al.size()); + System.out.println("al.toString2-->" + al.toString()); + + String re1 = (String)al.remove(1); + System.out.println("remove index=1 :"); + System.out.println("re-->" + re1); + System.out.println("size2-->" + al.size()); + System.out.println("al.toString2-->" + al.toString()); + } + +} diff --git a/group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java b/group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java new file mode 100644 index 0000000000..8c60d97513 --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java @@ -0,0 +1,27 @@ +import org.junit.Test; +import week1.homework.binaryNodeTree.BinaryTreeNode; + +/** + * @author : 温友朝 + * @date : 2017/4/5 + */ +public class BinaryNodeTreeTest { + +// @Test +// public BinaryTreeNode getTree(){ +// BinaryTreeNode btn = new BinaryTreeNode(5); +// btn.setData(3); +// +// return btn; +// } + + @Test + public void testAdd(){ + BinaryTreeNode btn = new BinaryTreeNode(5); + btn.setData(3); + btn.setData(7); + btn.setData(10); + btn.setData(6); + btn.setData(4); + } +} diff --git a/group24/75939388/learning2017/src/test/java/LinkedListTest.java b/group24/75939388/learning2017/src/test/java/LinkedListTest.java new file mode 100644 index 0000000000..5d7eb7b7bc --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/LinkedListTest.java @@ -0,0 +1,60 @@ +import org.junit.Test; +import week1.homework.linkedList.LinkedList; + +/** + * Created by macvi on 2017/4/3. + */ +public class LinkedListTest { + + @Test + public void testLinkedListAdd(){ + LinkedList ll = new LinkedList(); + ll.add("123"); + ll.add("456"); + ll.add("asdf"); + ll.add("zxcv"); + + System.out.println("ll.toString-->" + ll); + System.out.println("ll.size--->" + ll.size()); + } + + @Test + public void testLinkedListIndexAdd(){ + System.out.println("12345"); + } + + @Test + public void testGet(){ + LinkedList ll = new LinkedList(); + for(int i = 0; i < 10; i ++){ + ll.add(i + ""); + } + + System.out.println("get-->" + ll.get(9)); + System.out.println("ll.toString-->" + ll.toString() + "\nsize-->" + ll.size()); + } + + @Test + public void testIndexAdd(){ + LinkedList ll = new LinkedList(); + for(int i = 0; i < 5; i ++){ + ll.add(i + ""); + } + + ll.add(5, "xxoo"); + System.out.println("index get-->" + ll.get(0)); + System.out.println("ll.toString2-->" + ll.toString() + "\nsize-->" + ll.size()); + } + + @Test + public void testRemove(){ + LinkedList ll = new LinkedList(); + for(int i = 0; i < 6; i ++){ + ll.add(i + ""); + } + + Object removed = ll.remove(-1); + System.out.println("ll.toString-->" + ll.toString() + "\nsize-->" + ll.size()); + System.out.println("removed-->" + removed.toString()); + } +} diff --git a/group24/75939388/learning2017/src/test/java/QueueTest.java b/group24/75939388/learning2017/src/test/java/QueueTest.java new file mode 100644 index 0000000000..1630bf0372 --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/QueueTest.java @@ -0,0 +1,48 @@ +import org.junit.Assert; +import org.junit.Test; +import week1.homework.queue.Queue; + +/** + * Created by macvi on 2017/4/4. + */ +public class QueueTest { + + private Queue newQueue(){ + Queue q = new Queue(); + for(int i = 0; i < 13; i++){ + q.enQueue(i + ""); + } + + return q; + } + + @Test + public void testEnqueue(){ + Queue q = newQueue(); + q.enQueue(10 + ""); + q.enQueue( "xxoo"); + System.out.println("queue-->" + q.toString()); + } + + @Test + public void testSize(){ + Queue q = newQueue(); + + Assert.assertEquals(13, q.size()); + } + + @Test + public void testDequeue(){ + Queue q = newQueue(); + Object obj = q.deQueue(); + + Assert.assertEquals("0", obj); + } + + @Test + public void testIsEmpty(){ + Queue q = newQueue(); + + Assert.assertEquals(false, q.isEmpty()); + } +} diff --git a/group24/75939388/learning2017/src/test/java/StackTest.java b/group24/75939388/learning2017/src/test/java/StackTest.java new file mode 100644 index 0000000000..ae96d3de96 --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/StackTest.java @@ -0,0 +1,47 @@ +import org.junit.Assert; +import org.junit.Test; +import week1.homework.stack.Stack; + +/** + * Created by macvi on 2017/4/4. + */ +public class StackTest { + + private Stack getStack(){ + Stack s = new Stack(); + for(int i = 0; i < 14; i ++){ + s.push(i + ""); + } + + return s; + } + + @Test + public void pushTest(){ + Stack s = getStack(); + + System.out.println("stack-->" + s.toString()); + } + + @Test + public void testSize(){ + Stack s = getStack(); + + Assert.assertEquals(14, s.size()); + } + + @Test + public void testPeek(){ + Stack s = getStack(); + + Assert.assertEquals("13", s.peek()); + } + + @Test + public void testPop(){ + Stack s = getStack(); + + Assert.assertEquals("13", s.pop()); + Assert.assertEquals(13, s.size()); + } +} From 7d428741fc9f5d1c2de01a89f7fa712a0b88209b Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Wed, 5 Apr 2017 16:59:33 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group24/75939388/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 group24/75939388/.gitignore diff --git a/group24/75939388/.gitignore b/group24/75939388/.gitignore new file mode 100644 index 0000000000..596bd7346d --- /dev/null +++ b/group24/75939388/.gitignore @@ -0,0 +1,4 @@ +*.class +target/ +*.iml +.idea/ \ No newline at end of file From a6b10edd53d5d5630561d223c6b3a5190629759e Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Wed, 5 Apr 2017 17:38:58 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E7=AC=AC=E4=BA=8C=E5=91=A8=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E9=A2=84=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/week2/homework/array/ArrayUtil.java | 24 ++++++++++++++-- .../test/java/{ => week1}/ArrayListTest.java | 2 ++ .../java/{ => week1}/BinaryNodeTreeTest.java | 2 ++ .../test/java/{ => week1}/LinkedListTest.java | 2 ++ .../src/test/java/{ => week1}/QueueTest.java | 2 ++ .../src/test/java/{ => week1}/StackTest.java | 2 ++ .../src/test/java/week2/ArrayUtilTest.java | 28 +++++++++++++++++++ 7 files changed, 59 insertions(+), 3 deletions(-) rename group24/75939388/learning2017/src/test/java/{ => week1}/ArrayListTest.java (99%) rename group24/75939388/learning2017/src/test/java/{ => week1}/BinaryNodeTreeTest.java (97%) rename group24/75939388/learning2017/src/test/java/{ => week1}/LinkedListTest.java (98%) rename group24/75939388/learning2017/src/test/java/{ => week1}/QueueTest.java (98%) rename group24/75939388/learning2017/src/test/java/{ => week1}/StackTest.java (98%) create mode 100644 group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java index 1c619a402e..6885c88065 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java +++ b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java @@ -13,7 +13,12 @@ public class ArrayUtil { * @return */ public void reverseArray(int[] origin){ - + int length = origin.length; + int[] reversed = new int[length]; + for(int i = length - 1; i >= 0; i--){ + reversed[length - i - 1] = origin[i]; + } +// System.out.println(Arrays.toString(reversed)); } /** @@ -25,7 +30,20 @@ public void reverseArray(int[] origin){ */ public int[] removeZero(int[] oldArray){ - return null; + int length = oldArray.length; + int[] arr = new int[length]; + int index = 0; + for(int i = 0; i < length; i++){ + if(oldArray[i] != 0){ + arr[index] = oldArray[i]; + index ++; + } + } + //非0的数据个数 + int count = length - index - 1; + int[] newArr = new int[count]; + System.arraycopy(arr, 0, newArr, 0, count); + return newArr; } /** @@ -88,7 +106,7 @@ public int[] getPerfectNumbers(int max){ * 例如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/group24/75939388/learning2017/src/test/java/ArrayListTest.java b/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java similarity index 99% rename from group24/75939388/learning2017/src/test/java/ArrayListTest.java rename to group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java index a445b1eb02..b997eede13 100644 --- a/group24/75939388/learning2017/src/test/java/ArrayListTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java @@ -1,3 +1,5 @@ +package week1; + import org.junit.Test; import week1.homework.arrayList.ArrayList; diff --git a/group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java b/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java similarity index 97% rename from group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java rename to group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java index 8c60d97513..a0932adc46 100644 --- a/group24/75939388/learning2017/src/test/java/BinaryNodeTreeTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java @@ -1,3 +1,5 @@ +package week1; + import org.junit.Test; import week1.homework.binaryNodeTree.BinaryTreeNode; diff --git a/group24/75939388/learning2017/src/test/java/LinkedListTest.java b/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java similarity index 98% rename from group24/75939388/learning2017/src/test/java/LinkedListTest.java rename to group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java index 5d7eb7b7bc..7801445749 100644 --- a/group24/75939388/learning2017/src/test/java/LinkedListTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java @@ -1,3 +1,5 @@ +package week1; + import org.junit.Test; import week1.homework.linkedList.LinkedList; diff --git a/group24/75939388/learning2017/src/test/java/QueueTest.java b/group24/75939388/learning2017/src/test/java/week1/QueueTest.java similarity index 98% rename from group24/75939388/learning2017/src/test/java/QueueTest.java rename to group24/75939388/learning2017/src/test/java/week1/QueueTest.java index 1630bf0372..d36e69ee54 100644 --- a/group24/75939388/learning2017/src/test/java/QueueTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/QueueTest.java @@ -1,3 +1,5 @@ +package week1; + import org.junit.Assert; import org.junit.Test; import week1.homework.queue.Queue; diff --git a/group24/75939388/learning2017/src/test/java/StackTest.java b/group24/75939388/learning2017/src/test/java/week1/StackTest.java similarity index 98% rename from group24/75939388/learning2017/src/test/java/StackTest.java rename to group24/75939388/learning2017/src/test/java/week1/StackTest.java index ae96d3de96..fddf31e668 100644 --- a/group24/75939388/learning2017/src/test/java/StackTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/StackTest.java @@ -1,3 +1,5 @@ +package week1; + import org.junit.Assert; import org.junit.Test; import week1.homework.stack.Stack; diff --git a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java new file mode 100644 index 0000000000..f5fc3aa232 --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java @@ -0,0 +1,28 @@ +package week2; + +import org.junit.Test; +import week2.homework.array.ArrayUtil; + +import java.util.Arrays; + +/** + * @author : 温友朝 + * @date : 2017/4/5 + */ +public class ArrayUtilTest { + + @Test + public void testReverse(){ + ArrayUtil au = new ArrayUtil(); + int[] arr = {1, 2, 3, 4, 5}; + au.reverseArray(arr); + } + + @Test + public void testTrim(){ + int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; + ArrayUtil au = new ArrayUtil(); + int[] arr = au.removeZero(oldArr); + Arrays.toString(arr); + } +} From 210812665a22e8304dc665c2c0d1518d0ef1aab2 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Wed, 5 Apr 2017 19:08:22 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0pom.xml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group24/75939388/learning2017/pom.xml | 57 +++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 group24/75939388/learning2017/pom.xml diff --git a/group24/75939388/learning2017/pom.xml b/group24/75939388/learning2017/pom.xml new file mode 100644 index 0000000000..862e3d4d02 --- /dev/null +++ b/group24/75939388/learning2017/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + me.wyc + learning2017 + 1.0-SNAPSHOT + + + 1.7 + 1.7 + UTF-8 + UTF-8 + UTF-8 + + + + + aliyun + aliyun + http://maven.aliyun.com/nexus/content/groups/public + + true + never + + + false + + + + + + + aliyun + aliyun + http://maven.aliyun.com/nexus/content/groups/public + + true + + + false + + + + + + + + + junit + junit + 4.12 + + + \ No newline at end of file From 1a7f840ae24650fd09ab5f8065e6397f97b6f221 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Thu, 6 Apr 2017 00:08:57 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E7=AC=AC=E4=BA=8C=E5=91=A8=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E9=83=A8=E5=88=86=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/week2/homework/array/ArrayUtil.java | 126 +++++++++++++++--- .../src/test/java/week2/ArrayUtilTest.java | 37 ++++- 2 files changed, 138 insertions(+), 25 deletions(-) diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java index 6885c88065..28ccd50553 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java +++ b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java @@ -7,15 +7,16 @@ public class ArrayUtil { /** * 给定一个整形数组a , 对该数组的值进行置换 - 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] - 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * 例如: 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){ + public void reverseArray(int[] origin) { int length = origin.length; int[] reversed = new int[length]; - for(int i = length - 1; i >= 0; i--){ + for (int i = length - 1; i >= 0; i--) { reversed[length - i - 1] = origin[i]; } // System.out.println(Arrays.toString(reversed)); @@ -25,79 +26,163 @@ 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){ + public int[] removeZero(int[] oldArray) { int length = oldArray.length; int[] arr = new int[length]; int index = 0; - for(int i = 0; i < length; i++){ - if(oldArray[i] != 0){ + for (int i = 0; i < length; i++) { + if (oldArray[i] != 0) { arr[index] = oldArray[i]; - index ++; + index++; } } //非0的数据个数 - int count = length - index - 1; - int[] newArr = new int[count]; - System.arraycopy(arr, 0, newArr, 0, count); + int[] newArr = new int[index]; + System.arraycopy(arr, 0, newArr, 0, 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 int[] merge(int[] array1, int[] array2){ - return null; + public int[] merge(int[] array1, int[] array2) { + int length1 = array1.length; + int length2 = array2.length; + int[] arr = new int[length1 + length2]; + + System.arraycopy(array1, 0, arr, 0, length1); + System.arraycopy(array2, 0, arr, length1, length2); + + //去重 + for(int i = 0; i < arr.length; i++){ + for(int j = 0; j < arr.length; j++){ + if(i != j && arr[i] == arr[j]){ + arr[j] = 0; + } + } + } + + + int[] data = removeZero(arr); + int length = data.length; + + //排序 + for (int i = 0; i < length; i++) { + for(int j = 0; j < length; j++){ + if(data[i] < data[j]){ + int tmp = data[i]; + data[i] = data[j]; + data[j] = tmp; + } + } + } + return data; } + + /** * 把一个已经存满数据的数组 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; + public int[] grow(int[] oldArray, int size) { + int[] arr = new int[oldArray.length + size]; + System.arraycopy(oldArray, 0, arr, 0, oldArray.length); + return arr; } /** * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] * max = 1, 则返回空数组 [] + * F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) * @param max * @return */ - public int[] fibonacci(int max){ + public int[] fibonacci(int max) { + int[] empty = {}; + int[] arr2 = {1, 1}; + + switch (max){ + case 0 : return empty; + case 1 : return empty; + case 2 : return arr2; + default: { + int[] data = arr2; + int d = data[0] + data[1]; + while (d < max){ + int length = data.length; + d = data[length - 1] + data[length - 2]; + if(d > max){ + return data; + } + int[] temp = new int[data.length + 1]; + System.arraycopy(data, 0, temp, 0, length); + temp[length] = d; + + data = temp; + } + } + } + return null; } /** * 返回小于给定最大值max的所有素数数组 * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * * @param max * @return */ - public int[] getPrimes(int max){ - return null; + public int[] getPrimes(int max) { + int[] data = new int[max]; + int index = 0; + for(int i = 1; i < max; i++){ + int divided = 0; + for(int j = i; j >= 1; j--){ + if(i % j == 0){ + divided++; + } + if(divided > 2){ + break; + }else if(j == 1 && divided == 2){ + data[index] = i; + index ++; + } + } + } + + int[] result = new int[index]; + System.arraycopy(data, 0, result, 0, index); + return result; + } /** * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * * @param max * @return */ - public int[] getPerfectNumbers(int max){ + public int[] getPerfectNumbers(int max) { return null; } @@ -105,11 +190,12 @@ public int[] getPerfectNumbers(int max){ * 用seperator 把数组 array给连接起来 * 例如array= [3,8,9], seperator = "-" * 则返回值为"3-8-9" + * * @param array * @param seperator * @return */ - public String join(int[] array, String seperator){ + public String join(int[] array, String seperator) { return null; } } diff --git a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java index f5fc3aa232..9bd093fa83 100644 --- a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java +++ b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java @@ -10,19 +10,46 @@ * @date : 2017/4/5 */ public class ArrayUtilTest { + ArrayUtil au = new ArrayUtil(); @Test public void testReverse(){ - ArrayUtil au = new ArrayUtil(); int[] arr = {1, 2, 3, 4, 5}; - au.reverseArray(arr); + this.au.reverseArray(arr); } @Test public void testTrim(){ int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; - ArrayUtil au = new ArrayUtil(); - int[] arr = au.removeZero(oldArr); - Arrays.toString(arr); + int[] arr = this.au.removeZero(oldArr); + System.out.println(Arrays.toString(arr)); + } + + @Test + public void testMerge(){ + int[] a1 = {3, 5, 7,8}; + int[] a2 = {4, 5, 6,7}; + + int[] arr = this.au.merge(a1, a2); + System.out.println(Arrays.toString(arr)); + } + + @Test + public void testGrow(){ + int[] arr = {1, 2, 3, 4, 5}; + int[] arr2 = this.au.grow(arr, 4); + System.out.println(Arrays.toString(arr2)); + } + + @Test + public void testFibonacci(){ + int[] arr = this.au.fibonacci(100); + System.out.println(Arrays.toString(arr)); + } + + @Test + public void testPrimes(){ + int[] arr = this.au.getPrimes(100000); + System.out.println(Arrays.toString(arr)); } } From 9f1c6bce30277581bd76e23978d7835b7dc2c45d Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Thu, 6 Apr 2017 10:45:37 +0800 Subject: [PATCH 06/19] =?UTF-8?q?ArrayUtil=E4=BD=9C=E4=B8=9A=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/week2/homework/array/ArrayUtil.java | 34 +++++++++++++++++-- .../src/test/java/week2/ArrayUtilTest.java | 12 +++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java index 28ccd50553..f6823e5ba6 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java +++ b/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java @@ -183,7 +183,33 @@ public int[] getPrimes(int max) { * @return */ public int[] getPerfectNumbers(int max) { - return null; + int[] perfd = new int[max]; + int perfIndex = 0; + for(int i = 1; i <= max; i++){ + int index = 0; + int[] data = new int[i]; + for(int j = i - 1; j >= 1; j--){ + if(i % j == 0){ + data[index] = j; + index ++; + } + + if(j == 1 && getSum(data) == i){ + perfd[perfIndex] = i; + perfIndex++; + } + } + } + + return removeZero(perfd); + } + + private int getSum(int[] arr){ + int sum = 0; + for(int i : arr){ + sum += i; + } + return sum; } /** @@ -196,6 +222,10 @@ public int[] getPerfectNumbers(int max) { * @return */ public String join(int[] array, String seperator) { - return null; + StringBuffer sb = new StringBuffer(); + for(int i : array){ + sb.append(i).append(seperator); + } + return sb.substring(0, sb.length() - 1).toString(); } } diff --git a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java index 9bd093fa83..f519d7a7b7 100644 --- a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java +++ b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java @@ -52,4 +52,16 @@ public void testPrimes(){ int[] arr = this.au.getPrimes(100000); System.out.println(Arrays.toString(arr)); } + + @Test + public void testPerfectNumbers(){ + int[] arr = this.au.getPerfectNumbers(10000); + System.out.println(Arrays.toString(arr)); + } + + @Test + public void testJoin(){ + int[] arr = this.au.getPerfectNumbers(10000); + System.out.println(this.au.join(arr, "-")); + } } From 2ebba2e9db5e7f4d6480d161f3b623ec22dc9527 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Thu, 6 Apr 2017 13:34:34 +0800 Subject: [PATCH 07/19] =?UTF-8?q?liteStruts=E4=BD=9C=E4=B8=9A=E6=9A=82?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework/liteStruts/LoginAction.java | 39 +++++++++++++++++++ .../week2/homework/liteStruts/Struts.java | 29 ++++++++++++++ .../java/week2/homework/liteStruts/View.java | 23 +++++++++++ 3 files changed, 91 insertions(+) create mode 100644 group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java create mode 100644 group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java create mode 100644 group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java new file mode 100644 index 0000000000..ae3142e276 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java @@ -0,0 +1,39 @@ +package week2.homework.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/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java new file mode 100644 index 0000000000..4a5b2435d5 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java @@ -0,0 +1,29 @@ +package week2.homework.liteStruts; + +import java.util.Map; + + +public class Struts { + /** + * 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字段中。 + */ + public static View runAction(String actionName, Map parameters) { + + return null; + } + +} diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java new file mode 100644 index 0000000000..aff69f862c --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java @@ -0,0 +1,23 @@ +package week2.homework.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; + } +} From 4760fa9e8fbb08b0d3564cefe721c733a323cb4f Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Mon, 10 Apr 2017 17:15:50 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E7=AC=AC=E4=BA=8C=E5=91=A8=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group24/75939388/learning2017/pom.xml | 7 +++ .../homework/liteStruts/LoginAction.java | 2 +- .../week2/homework/liteStruts/ReadXML.java | 28 ++++++++++ .../week2/homework/liteStruts/Struts.java | 51 ++++++++++++++++++- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java diff --git a/group24/75939388/learning2017/pom.xml b/group24/75939388/learning2017/pom.xml index 862e3d4d02..9e5868fdcb 100644 --- a/group24/75939388/learning2017/pom.xml +++ b/group24/75939388/learning2017/pom.xml @@ -53,5 +53,12 @@ junit 4.12 + + + dom4j + dom4j + 1.6.1 + + \ No newline at end of file diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java index ae3142e276..3f1f357530 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java @@ -6,7 +6,7 @@ * */ public class LoginAction{ - private String name ; + private String name; private String password; private String message; diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java new file mode 100644 index 0000000000..1e07370332 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java @@ -0,0 +1,28 @@ +package week2.homework.liteStruts; + +import org.dom4j.Document; +import org.dom4j.io.SAXReader; + +import java.io.File; + +/** + * @author : 温友朝 + * @date : 2017/4/10 + */ +public class ReadXML { + Document document; + + public ReadXML(String filePath) throws Exception{ + SAXReader reader = new SAXReader(); + document = reader.read(new File(ReadXML.class.getResource("/").getFile()) + filePath); + } + + public String getActionClass(String actionName){ + return document.selectSingleNode("//action[@name='" + actionName + "']").valueOf("@class"); + } + + public String getJspPage(String actionName, String result){ + return document.selectSingleNode("//action[@name='" + actionName + "']") + .selectSingleNode("//result[@name='" + result + "']").getText(); + } +} diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java index 4a5b2435d5..794fc7af40 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java @@ -1,5 +1,6 @@ package week2.homework.liteStruts; +import java.lang.reflect.Method; import java.util.Map; @@ -22,8 +23,56 @@ public class Struts { * 放到View对象的jsp字段中。 */ public static View runAction(String actionName, Map parameters) { + try{ + //0. 读取配置文件struts.xml + ReadXML read = new ReadXML("/src/main/week2/homework/resources/struts.xml"); + //1. 找到对应的class + String className = read.getActionClass(actionName); + Class clz = Class.forName(className); + //得到对象 + Object la = clz.newInstance(); + setNameAndPassword(clz, la, parameters); + //2. 调用execute方法 + String result = invokeExecute(clz, la); + //3. 找到对象的所有getter方法 + getResultMap(clz, la, parameters); + //4. 确定使用哪一个jsp + String viewName = read.getJspPage(actionName, result); + View view = new View(); + view.setJsp(viewName); + view.setParameters(parameters); + return view; + }catch(Exception e){ + e.printStackTrace(); + return null; + } + } + + private static void setNameAndPassword(Class clz, Object la, Map parameters) throws Exception { + Method setName = clz.getDeclaredMethod("setName", String.class); + setName.invoke(la, parameters.get("name")); + + Method setPassword = clz.getDeclaredMethod("setPassword", String.class); + setPassword.invoke(la, parameters.get("password")); + } - return null; + private static String invokeExecute(Class clz, Object la)throws Exception{ + Method execute = clz.getDeclaredMethod("execute", null); + Method getMessage = clz.getDeclaredMethod("getMessage", null); + execute.invoke(la, null); + return getMessage.invoke(la, null).toString(); } + private static void getResultMap(Class clz, Object la, Map parameters) throws Exception{ + Method[] methods = clz.getMethods(); + for(Method me : methods){ + if(me.getName().startsWith("get")){ + String info = me.invoke(la, null).toString(); + String method= me.getName(); + String key = method.substring(3, method.length()).toLowerCase(); + parameters.put(key, info); + }else continue; + } + + } } From f1ef5703c670dd5d58d0751b715f6e2d48685ffb Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Mon, 10 Apr 2017 17:17:47 +0800 Subject: [PATCH 09/19] =?UTF-8?q?strutsTest=E4=BB=A3=E7=A0=81=E6=9A=82?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/week2/StrutsTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 group24/75939388/learning2017/src/test/java/week2/StrutsTest.java diff --git a/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java b/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java new file mode 100644 index 0000000000..07a723e0f2 --- /dev/null +++ b/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java @@ -0,0 +1,42 @@ +package week2; + +import org.junit.Assert; +import org.junit.Test; +import week2.homework.liteStruts.Struts; +import week2.homework.liteStruts.View; + +import java.util.HashMap; +import java.util.Map; + + +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")); + } +} From 32e4ec22b6dc97ee53a35420105b94c6862c0051 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Mon, 10 Apr 2017 17:42:35 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group24/75939388/learning2017/pom.xml | 7 +++++++ .../src/main/java/week2/homework/liteStruts/Struts.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/group24/75939388/learning2017/pom.xml b/group24/75939388/learning2017/pom.xml index 9e5868fdcb..75e8e10433 100644 --- a/group24/75939388/learning2017/pom.xml +++ b/group24/75939388/learning2017/pom.xml @@ -59,6 +59,13 @@ dom4j 1.6.1 + + + + jaxen + jaxen + 1.1.6 + \ No newline at end of file diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java index 794fc7af40..d105b3ee8c 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java +++ b/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java @@ -25,7 +25,7 @@ public class Struts { public static View runAction(String actionName, Map parameters) { try{ //0. 读取配置文件struts.xml - ReadXML read = new ReadXML("/src/main/week2/homework/resources/struts.xml"); + ReadXML read = new ReadXML("/resources/struts.xml"); //1. 找到对应的class String className = read.getActionClass(actionName); Class clz = Class.forName(className); From acb9797754b2d90cac5b0ac5f4b3988617267462 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Tue, 11 Apr 2017 11:27:01 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E7=AC=AC=E4=B8=89=E5=91=A8=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E4=B8=8B=E8=BD=BD=E4=BD=9C=E4=B8=9A=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework/download/DownloadThread.java | 21 ++++++ .../homework/download/FileDownloader.java | 67 +++++++++++++++++++ .../homework/download/FileDownloaderTest.java | 55 +++++++++++++++ .../homework/download/api/Connection.java | 23 +++++++ .../download/api/ConnectionException.java | 5 ++ .../download/api/ConnectionManager.java | 10 +++ .../download/api/DownloadListener.java | 5 ++ .../download/impl/ConnectionImpl.java | 20 ++++++ .../download/impl/ConnectionManagerImpl.java | 13 ++++ 9 files changed, 219 insertions(+) create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java create mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java new file mode 100644 index 0000000000..b81dc6f80a --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java @@ -0,0 +1,21 @@ +package week3.homework.download; + + +import week3.homework.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/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java new file mode 100644 index 0000000000..a0b75bdc26 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java @@ -0,0 +1,67 @@ +package week3.homework.download; + + +import week3.homework.download.api.Connection; +import week3.homework.download.api.ConnectionException; +import week3.homework.download.api.ConnectionManager; +import week3.homework.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/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java new file mode 100644 index 0000000000..0e6c5086a2 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java @@ -0,0 +1,55 @@ +package week3.homework.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import week3.homework.download.api.ConnectionManager; +import week3.homework.download.api.DownloadListener; +import week3.homework.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() { + + 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/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java new file mode 100644 index 0000000000..962c6227b0 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java @@ -0,0 +1,23 @@ +package week3.homework.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/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java new file mode 100644 index 0000000000..b97566660a --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package week3.homework.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java new file mode 100644 index 0000000000..99bdb2b098 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package week3.homework.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + Connection open(String url) throws ConnectionException; +} diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java new file mode 100644 index 0000000000..e0a72272e4 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package week3.homework.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..cb64bcbfb1 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java @@ -0,0 +1,20 @@ +package week3.homework.download.impl; + +import week3.homework.download.api.Connection; + +import java.io.IOException; + +public class ConnectionImpl implements Connection{ + + public byte[] read(int startPos, int endPos) throws IOException { + return new byte[0]; + } + + public int getContentLength() { + return 0; + } + + public void close() { + + } +} diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..22350ab447 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,13 @@ +package week3.homework.download.impl; + + +import week3.homework.download.api.Connection; +import week3.homework.download.api.ConnectionException; +import week3.homework.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + public Connection open(String url) throws ConnectionException { + return null; + } +} From 1b50dc1e2703eb94a7c87a9abeccc188be92e892 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Tue, 11 Apr 2017 21:56:45 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E6=9B=B4=E6=94=B9=EF=BC=8C=E9=80=82=E5=BA=94?= =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E8=8A=82=E5=A5=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataStructure}/array/ArrayUtil.java | 2 +- .../dataStructure}/arrayList/ArrayList.java | 5 +- .../binaryNodeTree/BinaryTreeNode.java | 2 +- .../dataStructure}/linkedList/LinkedList.java | 81 ++++++++++++++++++- .../java/basic/dataStructure/list/List.java | 12 +++ .../liteStruts/LoginAction.java | 2 +- .../dataStructure}/liteStruts/ReadXML.java | 2 +- .../dataStructure}/liteStruts/Struts.java | 2 +- .../dataStructure}/liteStruts/View.java | 2 +- .../dataStructure}/queue/Queue.java | 2 +- .../dataStructure}/stack/Stack.java | 4 +- .../thread}/download/DownloadThread.java | 4 +- .../thread}/download/FileDownloader.java | 10 +-- .../thread}/download/FileDownloaderTest.java | 8 +- .../thread}/download/api/Connection.java | 2 +- .../download/api/ConnectionException.java | 2 +- .../download/api/ConnectionManager.java | 2 +- .../download/api/DownloadListener.java | 2 +- .../thread}/download/impl/ConnectionImpl.java | 4 +- .../download/impl/ConnectionManagerImpl.java | 13 +++ .../main/java/week1/homework/list/List.java | 12 --- .../download/impl/ConnectionManagerImpl.java | 13 --- .../src/test/java/week1/ArrayListTest.java | 2 +- .../test/java/week1/BinaryNodeTreeTest.java | 2 +- .../src/test/java/week1/LinkedListTest.java | 2 +- .../src/test/java/week1/QueueTest.java | 2 +- .../src/test/java/week1/StackTest.java | 2 +- .../src/test/java/week2/ArrayUtilTest.java | 2 +- .../src/test/java/week2/StrutsTest.java | 4 +- 29 files changed, 139 insertions(+), 65 deletions(-) rename group24/75939388/learning2017/src/main/java/{week2/homework => basic/dataStructure}/array/ArrayUtil.java (99%) rename group24/75939388/learning2017/src/main/java/{week1/homework => basic/dataStructure}/arrayList/ArrayList.java (97%) rename group24/75939388/learning2017/src/main/java/{week1/homework => basic/dataStructure}/binaryNodeTree/BinaryTreeNode.java (96%) rename group24/75939388/learning2017/src/main/java/{week1/homework => basic/dataStructure}/linkedList/LinkedList.java (55%) create mode 100644 group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java rename group24/75939388/learning2017/src/main/java/{week2/homework => basic/dataStructure}/liteStruts/LoginAction.java (95%) rename group24/75939388/learning2017/src/main/java/{week2/homework => basic/dataStructure}/liteStruts/ReadXML.java (95%) rename group24/75939388/learning2017/src/main/java/{week2/homework => basic/dataStructure}/liteStruts/Struts.java (98%) rename group24/75939388/learning2017/src/main/java/{week2/homework => basic/dataStructure}/liteStruts/View.java (89%) rename group24/75939388/learning2017/src/main/java/{week1/homework => basic/dataStructure}/queue/Queue.java (97%) rename group24/75939388/learning2017/src/main/java/{week1/homework => basic/dataStructure}/stack/Stack.java (91%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/DownloadThread.java (77%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/FileDownloader.java (88%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/FileDownloaderTest.java (82%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/api/Connection.java (92%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/api/ConnectionException.java (60%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/api/ConnectionManager.java (82%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/api/DownloadListener.java (65%) rename group24/75939388/learning2017/src/main/java/{week3/homework => basic/thread}/download/impl/ConnectionImpl.java (74%) create mode 100644 group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java delete mode 100644 group24/75939388/learning2017/src/main/java/week1/homework/list/List.java delete mode 100644 group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayUtil.java similarity index 99% rename from group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayUtil.java index f6823e5ba6..f638839351 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/array/ArrayUtil.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayUtil.java @@ -1,4 +1,4 @@ -package week2.homework.array; +package basic.dataStructure.array; /** * @author : 温友朝 diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/arrayList/ArrayList.java similarity index 97% rename from group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/arrayList/ArrayList.java index 8d0b2c5d8a..f453e5e4e5 100644 --- a/group24/75939388/learning2017/src/main/java/week1/homework/arrayList/ArrayList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/arrayList/ArrayList.java @@ -1,7 +1,6 @@ -package week1.homework.arrayList; - -import week1.homework.list.List; +package basic.dataStructure.arrayList; +import basic.dataStructure.list.List; /** * Created by macvi on 2017/4/2. */ diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/binaryNodeTree/BinaryTreeNode.java similarity index 96% rename from group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/binaryNodeTree/BinaryTreeNode.java index a7da1d42da..9f506aaf99 100644 --- a/group24/75939388/learning2017/src/main/java/week1/homework/binaryNodeTree/BinaryTreeNode.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/binaryNodeTree/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package week1.homework.binaryNodeTree; +package basic.dataStructure.binaryNodeTree; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java similarity index 55% rename from group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java index c912377e62..617259bb44 100644 --- a/group24/75939388/learning2017/src/main/java/week1/homework/linkedList/LinkedList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java @@ -1,7 +1,6 @@ -package week1.homework.linkedList; - -import week1.homework.list.List; +package basic.dataStructure.linkedList; +import basic.dataStructure.list.List; /** * Created by macvi on 2017/4/3. */ @@ -126,4 +125,80 @@ public Node(Object obj, 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/group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java new file mode 100644 index 0000000000..c9df0db651 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java @@ -0,0 +1,12 @@ +package basic.dataStructure.list; + +/** + * Created by macvi on 2017/4/2. + */ +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/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/LoginAction.java similarity index 95% rename from group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/LoginAction.java index 3f1f357530..dfb9715fb4 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/LoginAction.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/LoginAction.java @@ -1,4 +1,4 @@ -package week2.homework.liteStruts; +package basic.dataStructure.liteStruts; /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/ReadXML.java similarity index 95% rename from group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/ReadXML.java index 1e07370332..ab2b6edf57 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/ReadXML.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/ReadXML.java @@ -1,4 +1,4 @@ -package week2.homework.liteStruts; +package basic.dataStructure.liteStruts; import org.dom4j.Document; import org.dom4j.io.SAXReader; diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/Struts.java similarity index 98% rename from group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/Struts.java index d105b3ee8c..c4265eeafe 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/Struts.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/Struts.java @@ -1,4 +1,4 @@ -package week2.homework.liteStruts; +package basic.dataStructure.liteStruts; import java.lang.reflect.Method; import java.util.Map; diff --git a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/View.java similarity index 89% rename from group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/View.java index aff69f862c..126c424e63 100644 --- a/group24/75939388/learning2017/src/main/java/week2/homework/liteStruts/View.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/View.java @@ -1,4 +1,4 @@ -package week2.homework.liteStruts; +package basic.dataStructure.liteStruts; import java.util.Map; diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java similarity index 97% rename from group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java index 3f6e3b94df..5096f9297c 100644 --- a/group24/75939388/learning2017/src/main/java/week1/homework/queue/Queue.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java @@ -1,4 +1,4 @@ -package week1.homework.queue; +package basic.dataStructure.queue; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java similarity index 91% rename from group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java index c451c28228..41c6f23064 100644 --- a/group24/75939388/learning2017/src/main/java/week1/homework/stack/Stack.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java @@ -1,6 +1,6 @@ -package week1.homework.stack; +package basic.dataStructure.stack; -import week1.homework.arrayList.ArrayList; +import basic.dataStructure.arrayList.ArrayList; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/DownloadThread.java similarity index 77% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/DownloadThread.java index b81dc6f80a..07fa272564 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/DownloadThread.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/DownloadThread.java @@ -1,7 +1,7 @@ -package week3.homework.download; +package basic.thread.download; -import week3.homework.download.api.Connection; +import basic.thread.download.api.Connection; public class DownloadThread extends Thread{ diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloader.java similarity index 88% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloader.java index a0b75bdc26..a9bfac68b7 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloader.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloader.java @@ -1,10 +1,10 @@ -package week3.homework.download; +package basic.thread.download; -import week3.homework.download.api.Connection; -import week3.homework.download.api.ConnectionException; -import week3.homework.download.api.ConnectionManager; -import week3.homework.download.api.DownloadListener; +import basic.thread.download.api.Connection; +import basic.thread.download.api.ConnectionException; +import basic.thread.download.api.ConnectionManager; +import basic.thread.download.api.DownloadListener; public class FileDownloader { diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloaderTest.java similarity index 82% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloaderTest.java index 0e6c5086a2..a4e5e4aeb1 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/FileDownloaderTest.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloaderTest.java @@ -1,11 +1,11 @@ -package week3.homework.download; +package basic.thread.download; import org.junit.After; import org.junit.Before; import org.junit.Test; -import week3.homework.download.api.ConnectionManager; -import week3.homework.download.api.DownloadListener; -import week3.homework.download.impl.ConnectionManagerImpl; +import basic.thread.download.api.ConnectionManager; +import basic.thread.download.api.DownloadListener; +import basic.thread.download.impl.ConnectionManagerImpl; public class FileDownloaderTest { diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/Connection.java similarity index 92% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/api/Connection.java index 962c6227b0..72552928b7 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/Connection.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/Connection.java @@ -1,4 +1,4 @@ -package week3.homework.download.api; +package basic.thread.download.api; import java.io.IOException; diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionException.java similarity index 60% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionException.java index b97566660a..64c33e4b2f 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionException.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionException.java @@ -1,4 +1,4 @@ -package week3.homework.download.api; +package basic.thread.download.api; public class ConnectionException extends Exception { diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionManager.java similarity index 82% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionManager.java index 99bdb2b098..da49063e33 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/ConnectionManager.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionManager.java @@ -1,4 +1,4 @@ -package week3.homework.download.api; +package basic.thread.download.api; public interface ConnectionManager { /** diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/DownloadListener.java similarity index 65% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/api/DownloadListener.java index e0a72272e4..80b1a4795b 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/api/DownloadListener.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/api/DownloadListener.java @@ -1,4 +1,4 @@ -package week3.homework.download.api; +package basic.thread.download.api; public interface DownloadListener { public void notifyFinished(); diff --git a/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionImpl.java similarity index 74% rename from group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java rename to group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionImpl.java index cb64bcbfb1..817ee4d37f 100644 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionImpl.java +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionImpl.java @@ -1,6 +1,6 @@ -package week3.homework.download.impl; +package basic.thread.download.impl; -import week3.homework.download.api.Connection; +import basic.thread.download.api.Connection; import java.io.IOException; diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..d0d318b33d --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,13 @@ +package basic.thread.download.impl; + + +import basic.thread.download.api.Connection; +import basic.thread.download.api.ConnectionException; +import basic.thread.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + public Connection open(String url) throws ConnectionException { + return null; + } +} diff --git a/group24/75939388/learning2017/src/main/java/week1/homework/list/List.java b/group24/75939388/learning2017/src/main/java/week1/homework/list/List.java deleted file mode 100644 index a33edd34fc..0000000000 --- a/group24/75939388/learning2017/src/main/java/week1/homework/list/List.java +++ /dev/null @@ -1,12 +0,0 @@ -package week1.homework.list; - -/** - * Created by macvi on 2017/4/2. - */ -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/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java b/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java deleted file mode 100644 index 22350ab447..0000000000 --- a/group24/75939388/learning2017/src/main/java/week3/homework/download/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package week3.homework.download.impl; - - -import week3.homework.download.api.Connection; -import week3.homework.download.api.ConnectionException; -import week3.homework.download.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - - public Connection open(String url) throws ConnectionException { - return null; - } -} diff --git a/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java b/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java index b997eede13..e7f19209a0 100644 --- a/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java @@ -1,7 +1,7 @@ package week1; import org.junit.Test; -import week1.homework.arrayList.ArrayList; +import basic.dataStructure.arrayList.ArrayList; /** * Created by macvi on 2017/4/2. diff --git a/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java b/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java index a0932adc46..3131b99666 100644 --- a/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java @@ -1,7 +1,7 @@ package week1; import org.junit.Test; -import week1.homework.binaryNodeTree.BinaryTreeNode; +import basic.dataStructure.binaryNodeTree.BinaryTreeNode; /** * @author : 温友朝 diff --git a/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java b/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java index 7801445749..35c15f9762 100644 --- a/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java @@ -1,7 +1,7 @@ package week1; import org.junit.Test; -import week1.homework.linkedList.LinkedList; +import basic.dataStructure.linkedList.LinkedList; /** * Created by macvi on 2017/4/3. diff --git a/group24/75939388/learning2017/src/test/java/week1/QueueTest.java b/group24/75939388/learning2017/src/test/java/week1/QueueTest.java index d36e69ee54..31760b3bc3 100644 --- a/group24/75939388/learning2017/src/test/java/week1/QueueTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/QueueTest.java @@ -2,7 +2,7 @@ import org.junit.Assert; import org.junit.Test; -import week1.homework.queue.Queue; +import basic.dataStructure.queue.Queue; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/test/java/week1/StackTest.java b/group24/75939388/learning2017/src/test/java/week1/StackTest.java index fddf31e668..3e9ac19d2f 100644 --- a/group24/75939388/learning2017/src/test/java/week1/StackTest.java +++ b/group24/75939388/learning2017/src/test/java/week1/StackTest.java @@ -2,7 +2,7 @@ import org.junit.Assert; import org.junit.Test; -import week1.homework.stack.Stack; +import basic.dataStructure.stack.Stack; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java index f519d7a7b7..2e9b9d4ada 100644 --- a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java +++ b/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java @@ -1,7 +1,7 @@ package week2; import org.junit.Test; -import week2.homework.array.ArrayUtil; +import basic.dataStructure.array.ArrayUtil; import java.util.Arrays; diff --git a/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java b/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java index 07a723e0f2..95181695cb 100644 --- a/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java +++ b/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java @@ -2,8 +2,8 @@ import org.junit.Assert; import org.junit.Test; -import week2.homework.liteStruts.Struts; -import week2.homework.liteStruts.View; +import basic.dataStructure.liteStruts.Struts; +import basic.dataStructure.liteStruts.View; import java.util.HashMap; import java.util.Map; From af00f492129c4619529bc05277b3a573b1078b1d Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Wed, 12 Apr 2017 00:18:00 +0800 Subject: [PATCH 13/19] =?UTF-8?q?linkedList=E4=BD=9C=E4=B8=9A=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{arrayList => }/ArrayList.java | 3 +- .../dataStructure/{array => }/ArrayUtil.java | 2 +- .../{binaryNodeTree => }/BinaryTreeNode.java | 2 +- .../{linkedList => }/LinkedList.java | 31 +++++++++++++-- .../basic/dataStructure/{list => }/List.java | 2 +- .../dataStructure/{queue => }/Queue.java | 2 +- .../dataStructure/{stack => }/Stack.java | 4 +- .../liteStruts/LoginAction.java | 2 +- .../liteStruts/ReadXML.java | 2 +- .../liteStruts/Struts.java | 2 +- .../{dataStructure => }/liteStruts/View.java | 2 +- .../download/impl/ConnectionManagerImpl.java | 13 ------- .../src/main/java/miniJVM/Demo.java | 7 ++++ .../thread/download/DownloadThread.java | 4 +- .../thread/download/FileDownloader.java | 10 ++--- .../thread/download/FileDownloaderTest.java | 8 ++-- .../thread/download/api/Connection.java | 2 +- .../download/api/ConnectionException.java | 2 +- .../download/api/ConnectionManager.java | 2 +- .../thread/download/api/DownloadListener.java | 2 +- .../thread/download/impl/ConnectionImpl.java | 4 +- .../download/impl/ConnectionManagerImpl.java | 13 +++++++ .../ArrayListTest.java | 4 +- .../ArrayUtilTest.java | 4 +- .../BinaryNodeTreeTest.java | 4 +- .../LinkedListTest.java | 38 ++++++++++++++++++- .../{week1 => data_structure}/QueueTest.java | 4 +- .../{week1 => data_structure}/StackTest.java | 4 +- .../{week2 => liteStruts}/StrutsTest.java | 6 +-- 29 files changed, 124 insertions(+), 61 deletions(-) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{arrayList => }/ArrayList.java (97%) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{array => }/ArrayUtil.java (99%) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{binaryNodeTree => }/BinaryTreeNode.java (96%) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{linkedList => }/LinkedList.java (87%) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{list => }/List.java (85%) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{queue => }/Queue.java (97%) rename group24/75939388/learning2017/src/main/java/basic/dataStructure/{stack => }/Stack.java (90%) rename group24/75939388/learning2017/src/main/java/basic/{dataStructure => }/liteStruts/LoginAction.java (95%) rename group24/75939388/learning2017/src/main/java/basic/{dataStructure => }/liteStruts/ReadXML.java (95%) rename group24/75939388/learning2017/src/main/java/basic/{dataStructure => }/liteStruts/Struts.java (98%) rename group24/75939388/learning2017/src/main/java/basic/{dataStructure => }/liteStruts/View.java (89%) delete mode 100644 group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java create mode 100644 group24/75939388/learning2017/src/main/java/miniJVM/Demo.java rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/DownloadThread.java (78%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/FileDownloader.java (89%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/FileDownloaderTest.java (83%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/api/Connection.java (92%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/api/ConnectionException.java (61%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/api/ConnectionManager.java (83%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/api/DownloadListener.java (66%) rename group24/75939388/learning2017/src/main/java/{basic => }/thread/download/impl/ConnectionImpl.java (75%) create mode 100644 group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java rename group24/75939388/learning2017/src/test/java/{week1 => data_structure}/ArrayListTest.java (96%) rename group24/75939388/learning2017/src/test/java/{week2 => data_structure}/ArrayUtilTest.java (95%) rename group24/75939388/learning2017/src/test/java/{week1 => data_structure}/BinaryNodeTreeTest.java (87%) rename group24/75939388/learning2017/src/test/java/{week1 => data_structure}/LinkedListTest.java (67%) rename group24/75939388/learning2017/src/test/java/{week1 => data_structure}/QueueTest.java (93%) rename group24/75939388/learning2017/src/test/java/{week1 => data_structure}/StackTest.java (93%) rename group24/75939388/learning2017/src/test/java/{week2 => liteStruts}/StrutsTest.java (91%) diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/arrayList/ArrayList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java similarity index 97% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/arrayList/ArrayList.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java index f453e5e4e5..0d68dfe4da 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/arrayList/ArrayList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java @@ -1,6 +1,5 @@ -package basic.dataStructure.arrayList; +package basic.dataStructure; -import basic.dataStructure.list.List; /** * Created by macvi on 2017/4/2. */ diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java similarity index 99% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayUtil.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java index f638839351..1fcf441f27 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayUtil.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java @@ -1,4 +1,4 @@ -package basic.dataStructure.array; +package basic.dataStructure; /** * @author : 温友朝 diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/binaryNodeTree/BinaryTreeNode.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/BinaryTreeNode.java similarity index 96% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/binaryNodeTree/BinaryTreeNode.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/BinaryTreeNode.java index 9f506aaf99..5050ae3c95 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/binaryNodeTree/BinaryTreeNode.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package basic.dataStructure.binaryNodeTree; +package basic.dataStructure; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java similarity index 87% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java index 617259bb44..6dd2e59375 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java @@ -1,6 +1,5 @@ -package basic.dataStructure.linkedList; +package basic.dataStructure; -import basic.dataStructure.list.List; /** * Created by macvi on 2017/4/3. */ @@ -130,8 +129,23 @@ public Node(Object obj, Node next) { * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ - public void reverse(){ + public void reverse(){ + int size = this.size(); + if(size == 1){ + return; + } + + Object[] data = new Object[size]; + for(int i = 0; i < size; i++){ + data[i] = this.get(i); + } + + this.head = new Node(); + + for(int i = size - 1; i >= 0; i--){ + this.add(data[i]); + } } /** @@ -141,7 +155,18 @@ public void reverse(){ */ public void removeFirstHalf(){ + int size = this.size(); + int index = this.size()/2; + ArrayList al = new ArrayList(); + for(int i = index; i < size; i++){ + al.add(this.get(i)); + } + this.head = new Node(); + + for(int i = 0; i < al.size(); i++){ + this.add(al.get(i)); + } } /** diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/List.java similarity index 85% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/List.java index c9df0db651..dc2a62aab3 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/list/List.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/List.java @@ -1,4 +1,4 @@ -package basic.dataStructure.list; +package basic.dataStructure; /** * Created by macvi on 2017/4/2. diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/Queue.java similarity index 97% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/Queue.java index 5096f9297c..36ca7e9647 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/Queue.java @@ -1,4 +1,4 @@ -package basic.dataStructure.queue; +package basic.dataStructure; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/Stack.java similarity index 90% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/Stack.java index 41c6f23064..bea16033fa 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/Stack.java @@ -1,6 +1,4 @@ -package basic.dataStructure.stack; - -import basic.dataStructure.arrayList.ArrayList; +package basic.dataStructure; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/LoginAction.java b/group24/75939388/learning2017/src/main/java/basic/liteStruts/LoginAction.java similarity index 95% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/LoginAction.java rename to group24/75939388/learning2017/src/main/java/basic/liteStruts/LoginAction.java index dfb9715fb4..14b8aba8e2 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/LoginAction.java +++ b/group24/75939388/learning2017/src/main/java/basic/liteStruts/LoginAction.java @@ -1,4 +1,4 @@ -package basic.dataStructure.liteStruts; +package basic.liteStruts; /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/ReadXML.java b/group24/75939388/learning2017/src/main/java/basic/liteStruts/ReadXML.java similarity index 95% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/ReadXML.java rename to group24/75939388/learning2017/src/main/java/basic/liteStruts/ReadXML.java index ab2b6edf57..458b247e18 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/ReadXML.java +++ b/group24/75939388/learning2017/src/main/java/basic/liteStruts/ReadXML.java @@ -1,4 +1,4 @@ -package basic.dataStructure.liteStruts; +package basic.liteStruts; import org.dom4j.Document; import org.dom4j.io.SAXReader; diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/Struts.java b/group24/75939388/learning2017/src/main/java/basic/liteStruts/Struts.java similarity index 98% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/Struts.java rename to group24/75939388/learning2017/src/main/java/basic/liteStruts/Struts.java index c4265eeafe..3b28f2bf60 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/Struts.java +++ b/group24/75939388/learning2017/src/main/java/basic/liteStruts/Struts.java @@ -1,4 +1,4 @@ -package basic.dataStructure.liteStruts; +package basic.liteStruts; import java.lang.reflect.Method; import java.util.Map; diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/View.java b/group24/75939388/learning2017/src/main/java/basic/liteStruts/View.java similarity index 89% rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/View.java rename to group24/75939388/learning2017/src/main/java/basic/liteStruts/View.java index 126c424e63..777380b8f9 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/liteStruts/View.java +++ b/group24/75939388/learning2017/src/main/java/basic/liteStruts/View.java @@ -1,4 +1,4 @@ -package basic.dataStructure.liteStruts; +package basic.liteStruts; import java.util.Map; diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java b/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java deleted file mode 100644 index d0d318b33d..0000000000 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionManagerImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package basic.thread.download.impl; - - -import basic.thread.download.api.Connection; -import basic.thread.download.api.ConnectionException; -import basic.thread.download.api.ConnectionManager; - -public class ConnectionManagerImpl implements ConnectionManager { - - public Connection open(String url) throws ConnectionException { - return null; - } -} diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/Demo.java b/group24/75939388/learning2017/src/main/java/miniJVM/Demo.java new file mode 100644 index 0000000000..565983ab06 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/miniJVM/Demo.java @@ -0,0 +1,7 @@ +package miniJVM; + +/** + * Created by macvi on 2017/4/11. + */ +public class Demo { +} diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/DownloadThread.java b/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java similarity index 78% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/DownloadThread.java rename to group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java index 07fa272564..3aede4ae04 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/DownloadThread.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java @@ -1,7 +1,7 @@ -package basic.thread.download; +package thread.download; -import basic.thread.download.api.Connection; +import thread.download.api.Connection; public class DownloadThread extends Thread{ diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloader.java b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java similarity index 89% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloader.java rename to group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java index a9bfac68b7..f1f2c3b4db 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloader.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java @@ -1,10 +1,10 @@ -package basic.thread.download; +package thread.download; -import basic.thread.download.api.Connection; -import basic.thread.download.api.ConnectionException; -import basic.thread.download.api.ConnectionManager; -import basic.thread.download.api.DownloadListener; +import thread.download.api.Connection; +import thread.download.api.ConnectionException; +import thread.download.api.ConnectionManager; +import thread.download.api.DownloadListener; public class FileDownloader { diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloaderTest.java b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java similarity index 83% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloaderTest.java rename to group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java index a4e5e4aeb1..3057663d0a 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/FileDownloaderTest.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java @@ -1,11 +1,11 @@ -package basic.thread.download; +package thread.download; import org.junit.After; import org.junit.Before; import org.junit.Test; -import basic.thread.download.api.ConnectionManager; -import basic.thread.download.api.DownloadListener; -import basic.thread.download.impl.ConnectionManagerImpl; +import thread.download.api.ConnectionManager; +import thread.download.api.DownloadListener; +import thread.download.impl.ConnectionManagerImpl; public class FileDownloaderTest { diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/Connection.java b/group24/75939388/learning2017/src/main/java/thread/download/api/Connection.java similarity index 92% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/api/Connection.java rename to group24/75939388/learning2017/src/main/java/thread/download/api/Connection.java index 72552928b7..08a85b35dd 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/Connection.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/api/Connection.java @@ -1,4 +1,4 @@ -package basic.thread.download.api; +package thread.download.api; import java.io.IOException; diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionException.java b/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java similarity index 61% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionException.java rename to group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java index 64c33e4b2f..d4f61f719c 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionException.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java @@ -1,4 +1,4 @@ -package basic.thread.download.api; +package thread.download.api; public class ConnectionException extends Exception { diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionManager.java b/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionManager.java similarity index 83% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionManager.java rename to group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionManager.java index da49063e33..f5f6c2ff70 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/ConnectionManager.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionManager.java @@ -1,4 +1,4 @@ -package basic.thread.download.api; +package thread.download.api; public interface ConnectionManager { /** diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/DownloadListener.java b/group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java similarity index 66% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/api/DownloadListener.java rename to group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java index 80b1a4795b..f5cf47d886 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/api/DownloadListener.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java @@ -1,4 +1,4 @@ -package basic.thread.download.api; +package thread.download.api; public interface DownloadListener { public void notifyFinished(); diff --git a/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java similarity index 75% rename from group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionImpl.java rename to group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java index 817ee4d37f..93239c6503 100644 --- a/group24/75939388/learning2017/src/main/java/basic/thread/download/impl/ConnectionImpl.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java @@ -1,6 +1,6 @@ -package basic.thread.download.impl; +package thread.download.impl; -import basic.thread.download.api.Connection; +import thread.download.api.Connection; import java.io.IOException; diff --git a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..2eb0c784ec --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,13 @@ +package thread.download.impl; + + +import thread.download.api.Connection; +import thread.download.api.ConnectionException; +import thread.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + public Connection open(String url) throws ConnectionException { + return null; + } +} diff --git a/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java b/group24/75939388/learning2017/src/test/java/data_structure/ArrayListTest.java similarity index 96% rename from group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java rename to group24/75939388/learning2017/src/test/java/data_structure/ArrayListTest.java index e7f19209a0..ee8ee6b0d0 100644 --- a/group24/75939388/learning2017/src/test/java/week1/ArrayListTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/ArrayListTest.java @@ -1,7 +1,7 @@ -package week1; +package data_structure; import org.junit.Test; -import basic.dataStructure.arrayList.ArrayList; +import basic.dataStructure.ArrayList; /** * Created by macvi on 2017/4/2. diff --git a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java b/group24/75939388/learning2017/src/test/java/data_structure/ArrayUtilTest.java similarity index 95% rename from group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java rename to group24/75939388/learning2017/src/test/java/data_structure/ArrayUtilTest.java index 2e9b9d4ada..1dc1a6f263 100644 --- a/group24/75939388/learning2017/src/test/java/week2/ArrayUtilTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/ArrayUtilTest.java @@ -1,7 +1,7 @@ -package week2; +package data_structure; import org.junit.Test; -import basic.dataStructure.array.ArrayUtil; +import basic.dataStructure.ArrayUtil; import java.util.Arrays; diff --git a/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java b/group24/75939388/learning2017/src/test/java/data_structure/BinaryNodeTreeTest.java similarity index 87% rename from group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java rename to group24/75939388/learning2017/src/test/java/data_structure/BinaryNodeTreeTest.java index 3131b99666..df976147e3 100644 --- a/group24/75939388/learning2017/src/test/java/week1/BinaryNodeTreeTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/BinaryNodeTreeTest.java @@ -1,7 +1,7 @@ -package week1; +package data_structure; import org.junit.Test; -import basic.dataStructure.binaryNodeTree.BinaryTreeNode; +import basic.dataStructure.BinaryTreeNode; /** * @author : 温友朝 diff --git a/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java b/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java similarity index 67% rename from group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java rename to group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java index 35c15f9762..ddcdfdb44d 100644 --- a/group24/75939388/learning2017/src/test/java/week1/LinkedListTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java @@ -1,13 +1,34 @@ -package week1; +package data_structure; +import org.junit.After; +import org.junit.Before; import org.junit.Test; -import basic.dataStructure.linkedList.LinkedList; +import basic.dataStructure.LinkedList; /** * Created by macvi on 2017/4/3. */ public class LinkedListTest { + LinkedList ll = new LinkedList(); + + @Before + public void init(){ + ll.add("123"); + ll.add("456"); + ll.add("asdf"); + ll.add("zxcv"); + ll.add("asasdasddf"); + ll.add("zxasdasdacv"); + ll.add("23423423v"); + } + + @After + public void destroy(){ + + } + + @Test public void testLinkedListAdd(){ LinkedList ll = new LinkedList(); @@ -16,6 +37,7 @@ public void testLinkedListAdd(){ ll.add("asdf"); ll.add("zxcv"); + System.out.println("ll.toString-->" + ll); System.out.println("ll.size--->" + ll.size()); } @@ -59,4 +81,16 @@ public void testRemove(){ System.out.println("ll.toString-->" + ll.toString() + "\nsize-->" + ll.size()); System.out.println("removed-->" + removed.toString()); } + + @Test + public void testReverse(){ + ll.reverse(); + System.out.println("ll.reverse-->" + ll.toString()); + } + + @Test + public void testRemoveFirstHalf(){ + ll.removeFirstHalf(); + System.out.println("ll.removeFirstHalf-->" + ll.toString()); + } } diff --git a/group24/75939388/learning2017/src/test/java/week1/QueueTest.java b/group24/75939388/learning2017/src/test/java/data_structure/QueueTest.java similarity index 93% rename from group24/75939388/learning2017/src/test/java/week1/QueueTest.java rename to group24/75939388/learning2017/src/test/java/data_structure/QueueTest.java index 31760b3bc3..3db6d82e49 100644 --- a/group24/75939388/learning2017/src/test/java/week1/QueueTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/QueueTest.java @@ -1,8 +1,8 @@ -package week1; +package data_structure; import org.junit.Assert; import org.junit.Test; -import basic.dataStructure.queue.Queue; +import basic.dataStructure.Queue; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/test/java/week1/StackTest.java b/group24/75939388/learning2017/src/test/java/data_structure/StackTest.java similarity index 93% rename from group24/75939388/learning2017/src/test/java/week1/StackTest.java rename to group24/75939388/learning2017/src/test/java/data_structure/StackTest.java index 3e9ac19d2f..b933b8b63e 100644 --- a/group24/75939388/learning2017/src/test/java/week1/StackTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/StackTest.java @@ -1,8 +1,8 @@ -package week1; +package data_structure; import org.junit.Assert; import org.junit.Test; -import basic.dataStructure.stack.Stack; +import basic.dataStructure.Stack; /** * Created by macvi on 2017/4/4. diff --git a/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java b/group24/75939388/learning2017/src/test/java/liteStruts/StrutsTest.java similarity index 91% rename from group24/75939388/learning2017/src/test/java/week2/StrutsTest.java rename to group24/75939388/learning2017/src/test/java/liteStruts/StrutsTest.java index 95181695cb..4477c5f51b 100644 --- a/group24/75939388/learning2017/src/test/java/week2/StrutsTest.java +++ b/group24/75939388/learning2017/src/test/java/liteStruts/StrutsTest.java @@ -1,9 +1,9 @@ -package week2; +package liteStruts; import org.junit.Assert; import org.junit.Test; -import basic.dataStructure.liteStruts.Struts; -import basic.dataStructure.liteStruts.View; +import basic.liteStruts.Struts; +import basic.liteStruts.View; import java.util.HashMap; import java.util.Map; From f08de628fa7bef6bb716c73b05ea237cd9cd7fd8 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Wed, 12 Apr 2017 17:40:26 +0800 Subject: [PATCH 14/19] =?UTF-8?q?linkedList=E4=BD=9C=E4=B8=9A=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/basic/dataStructure/LinkedList.java | 102 ++++++++++++++++-- .../java/data_structure/LinkedListTest.java | 43 ++++++-- 2 files changed, 129 insertions(+), 16 deletions(-) diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java index 6dd2e59375..048928d325 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java @@ -175,7 +175,9 @@ public void removeFirstHalf(){ * @param length */ public void remove(int i, int length){ - + for(int j = i; j < i + length; j++){ + this.remove(i); + } } /** * 假定当前链表和listB均包含已升序排列的整数 @@ -186,7 +188,14 @@ public void remove(int i, int length){ * @param list */ public int[] getElements(LinkedList list){ - return null; + int size = list.size(); + int[] arr = new int[size]; + for(int i = 0; i < size; i++){ + int index = (Integer) list.get(i); + arr[i] = (Integer) this.get(index); + } + + return arr; } /** @@ -196,7 +205,26 @@ public int[] getElements(LinkedList list){ * @param list */ - public void subtract(LinkedList list){ + public void subtract(LinkedList list){ + int lSize = list.size(); + int size = this.size(); + + ArrayList indexList = new ArrayList(); + for(int i = 0; i < lSize; i++){ + Node temp = this.head; + int index = 0; + while (temp.next != null){ + if(list.get(i) == temp.data){ + indexList.add(index); + } + temp = temp.next; + index++; + } + } + + for(int i = 0; i < indexList.size(); i ++){ + this.remove(i); + } } @@ -204,8 +232,30 @@ public void subtract(LinkedList list){ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ - public void removeDuplicateValues(){ + public void removeDuplicateValues(){ + int size = this.size(); + ArrayList list = new ArrayList(); + int[] duplicate = new int[size]; + for(int i = 0; i < size; i ++){ + int index = 0; + int value = (Integer)this.get(i); + for(int j = i; j < size; j ++){ + int val = (Integer)this.get(j); + if(value == val){ + index ++; + } + + if(index >= 2){ + list.add(j); + } + } + } + int lSize = list.size(); + for(int i = 0; i < lSize; i ++){ + int index = (Integer)list.get(i); + this.remove(index); + } } /** @@ -214,8 +264,14 @@ public void removeDuplicateValues(){ * @param min * @param max */ - public void removeRange(int min, int max){ - + public void removeRange(int min, int max){ + int size = this.size(); + for(int i = 0; i < size; i ++){ + int value = (Integer) this.get(i); + if(value > min && value < max){ + this.remove(i); + } + } } /** @@ -223,7 +279,37 @@ public void removeRange(int min, int max){ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ - public LinkedList intersection( LinkedList list){ - return null; + public LinkedList intersection( LinkedList list){ + //组合成新的链表 + int listSize = list.size(); + for(int i = 0 ; i < listSize; i ++){ + this.add(list.get(i)); + } + + //转化成数组 + int size = this.size(); + int[] arr = new int[size]; + for(int i = 0; i < size; i++){ + arr[i] = (Integer)this.get(i); + } + + //排序 + for(int i = 0; i < size - 1; i ++){ + int temp = arr[i]; + for(int j = i; j < size - 1; j ++){ + if(temp > arr[j + 1]){ + arr[j] = arr[j + 1]; + temp = arr[j]; + } + } + } + + //组装 + LinkedList li = new LinkedList(); + for(int i = 0; i < size; i ++){ + li.add(arr[i]); + } + + return li; } } diff --git a/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java b/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java index ddcdfdb44d..223c0ea20b 100644 --- a/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java @@ -1,9 +1,11 @@ package data_structure; +import basic.dataStructure.LinkedList; import org.junit.After; import org.junit.Before; import org.junit.Test; -import basic.dataStructure.LinkedList; + +import java.util.Arrays; /** * Created by macvi on 2017/4/3. @@ -14,13 +16,9 @@ public class LinkedListTest { @Before public void init(){ - ll.add("123"); - ll.add("456"); - ll.add("asdf"); - ll.add("zxcv"); - ll.add("asasdasddf"); - ll.add("zxasdasdacv"); - ll.add("23423423v"); + for(int i = 0; i < 10; i++){ + ll.add(i); + } } @After @@ -93,4 +91,33 @@ public void testRemoveFirstHalf(){ ll.removeFirstHalf(); System.out.println("ll.removeFirstHalf-->" + ll.toString()); } + + @Test + public void testRemoveL(){ + ll.remove(2, 5); + System.out.println("ll.toString-->" + ll.toString()); + } + + @Test + public void testGetElements(){ + LinkedList l2 = new LinkedList(); + l2.add(3); + l2.add(5); + l2.add(9); + l2.add(0); + + int[] arr = ll.getElements(l2); + System.out.println("arr->" + Arrays.toString(arr)); + } + + @Test + public void testRemoveDuplicate(){ + ll.add(1); + ll.add(3); + ll.add(4); + ll.add(10); + ll.add(11); + ll.removeDuplicateValues(); + System.out.println("ll.toString-->" + ll.toString()); + } } From c9183ca2c29a58c1fa6526cbec2d26eb88406899 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Thu, 13 Apr 2017 13:55:04 +0800 Subject: [PATCH 15/19] =?UTF-8?q?linkedList=E6=95=B0=E6=8D=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=BD=9C=E4=B8=9A=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/basic/dataStructure/ArrayList.java | 10 ++ .../java/basic/dataStructure/ArrayUtil.java | 16 ++- .../java/basic/dataStructure/LinkedList.java | 104 +++++++++++------- .../java/data_structure/LinkedListTest.java | 30 ++++- 4 files changed, 119 insertions(+), 41 deletions(-) diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java index 0d68dfe4da..8ae862da33 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java @@ -88,6 +88,16 @@ public int size() { return size; } + public boolean contains(Object obj){ + for(int i = 0; i < this.size(); i++){ + if(obj == this.get(i)){ + return true; + } + } + + return false; + } + @Override public String toString() { StringBuffer sb = new StringBuffer(); diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java index 1fcf441f27..22bccaaf5b 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayUtil.java @@ -19,7 +19,6 @@ public void reverseArray(int[] origin) { for (int i = length - 1; i >= 0; i--) { reversed[length - i - 1] = origin[i]; } -// System.out.println(Arrays.toString(reversed)); } /** @@ -47,6 +46,21 @@ public int[] removeZero(int[] oldArray) { return newArr; } + public static Object[] remove(Object[] oldArray, Object value){ + int length = oldArray.length; + Object[] arr = new Object[length]; + int index = 0; + for (int i = 0; i < length; i++) { + if (oldArray[i] != value) { + arr[index] = oldArray[i]; + index++; + } + } + Object[] newArr = new Object[index]; + System.arraycopy(arr, 0, newArr, 0, 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] , 注意: 已经消除了重复 diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java index 048928d325..3ac85ad37b 100644 --- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java +++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java @@ -98,6 +98,25 @@ public int size() { return size; } + public void asList(Object[] array){ + LinkedList list = new LinkedList(); + for(int i = 0; i < array.length; i++){ + list.add(array[i]); + } + + this.head = list.head; + } + + public Object[] toArray(LinkedList list){ + int size = list.size(); + Object[] arr = new Object[size]; + for(int i = 0; i < size; i++){ + arr[i] = list.get(i); + } + + return arr; + } + public String toString() { StringBuffer sb = new StringBuffer(); Node temp = this.head; @@ -206,26 +225,13 @@ public int[] getElements(LinkedList list){ */ public void subtract(LinkedList list){ - int lSize = list.size(); - int size = this.size(); - - ArrayList indexList = new ArrayList(); - for(int i = 0; i < lSize; i++){ - Node temp = this.head; - int index = 0; - while (temp.next != null){ - if(list.get(i) == temp.data){ - indexList.add(index); - } - temp = temp.next; - index++; - } - } - - for(int i = 0; i < indexList.size(); i ++){ - this.remove(i); + Object[] arr1 = toArray(this); + Object[] arr2 = toArray(list); + for(int i = 0; i < arr2.length; i++){ + arr1 = ArrayUtil.remove(arr1, arr2[i]); } + asList(arr1); } /** @@ -234,28 +240,36 @@ public void subtract(LinkedList list){ */ public void removeDuplicateValues(){ int size = this.size(); - ArrayList list = new ArrayList(); - int[] duplicate = new int[size]; + ArrayList indexList = new ArrayList(); + ArrayList valueList = new ArrayList(); for(int i = 0; i < size; i ++){ + int valueI = (Integer)this.get(i); int index = 0; - int value = (Integer)this.get(i); - for(int j = i; j < size; j ++){ - int val = (Integer)this.get(j); - if(value == val){ - index ++; + for(int j = i + 1; j < size; j++){ + if(valueList.contains(valueI)){ + continue; + } + int valueJ = (Integer) this.get(j); + if(valueJ == valueI){ + index++; } - if(index >= 2){ - list.add(j); + if(index > 0){ + indexList.add(j); + valueList.add(valueJ); } } } - int lSize = list.size(); - for(int i = 0; i < lSize; i ++){ - int index = (Integer)list.get(i); - this.remove(index); + Object[] arr = new Object[size]; + for(int i = 0; i < size; i++){ + arr[i] = indexList.contains(i) ? false : this.get(i); } + + ArrayUtil au = new ArrayUtil(); + arr = au.remove(arr, false); + + asList(arr); } /** @@ -266,12 +280,26 @@ public void removeDuplicateValues(){ */ public void removeRange(int min, int max){ int size = this.size(); - for(int i = 0; i < size; i ++){ + int[] range = new int[max - min]; + int index = 0; + for(int i = 0; i < size; i++){ int value = (Integer) this.get(i); if(value > min && value < max){ - this.remove(i); + range[index] = value; + index++; } } + + Object[] arr = new Object[size]; + for(int i = 0; i < size; i++){ + arr[i] = this.get(i); + } + + for(int i = 0; i < range.length; i++){ + arr = ArrayUtil.remove(arr, range[i]); + } + + asList(arr); } /** @@ -292,14 +320,13 @@ public LinkedList intersection( LinkedList list){ for(int i = 0; i < size; i++){ arr[i] = (Integer)this.get(i); } - //排序 for(int i = 0; i < size - 1; i ++){ - int temp = arr[i]; - for(int j = i; j < size - 1; j ++){ - if(temp > arr[j + 1]){ + for(int j = 0; j < size - i - 1; j ++){ + if(arr[j] >= arr[j + 1]){ + int temp = arr[j]; arr[j] = arr[j + 1]; - temp = arr[j]; + arr[j + 1] = temp; } } } @@ -309,7 +336,6 @@ public LinkedList intersection( LinkedList list){ for(int i = 0; i < size; i ++){ li.add(arr[i]); } - return li; } } diff --git a/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java b/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java index 223c0ea20b..c98a305623 100644 --- a/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java +++ b/group24/75939388/learning2017/src/test/java/data_structure/LinkedListTest.java @@ -22,7 +22,7 @@ public void init(){ } @After - public void destroy(){ + public void print(){ } @@ -120,4 +120,32 @@ public void testRemoveDuplicate(){ ll.removeDuplicateValues(); System.out.println("ll.toString-->" + ll.toString()); } + + @Test + public void testRemoveRange(){ + ll.removeRange(2, 6); + System.out.println("ll.toString-->" + ll.toString()); + } + + @Test + public void testSubtract(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(5); + + ll.subtract(list); + System.out.println("ll.toString-->" + ll); + } + + @Test + public void testIntersection(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(5); + + LinkedList list2 = ll.intersection(list); + System.out.println(list2); + } } From d0e682275a01d5162198acdab64b8b0697a59dd3 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Thu, 13 Apr 2017 17:14:06 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E4=BB=A3=E7=A0=81=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/thread/download/DownloadThread.java | 8 +- .../java/thread/download/FileDownloader.java | 6 +- .../thread/download/FileDownloaderTest.java | 6 +- .../download/api/ConnectionException.java | 3 + .../thread/download/impl/ConnectionImpl.java | 86 +++++++++++++++++-- .../download/impl/ConnectionManagerImpl.java | 11 ++- .../download/impl/DownLoadListenerImpl.java | 13 +++ 7 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java diff --git a/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java b/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java index 3aede4ae04..a868f6b5bb 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java @@ -15,7 +15,11 @@ public DownloadThread( Connection conn, int startPos, int endPos){ this.startPos = startPos; this.endPos = endPos; } - public void run(){ - + public void run(){ + try{ + this.conn.read(this.startPos, this.endPos); + }catch(Exception e){ + e.printStackTrace(); + } } } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java index f1f2c3b4db..20084d4ddd 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java @@ -1,6 +1,5 @@ package thread.download; - import thread.download.api.Connection; import thread.download.api.ConnectionException; import thread.download.api.ConnectionManager; @@ -17,7 +16,6 @@ public class FileDownloader { public FileDownloader(String _url) { this.url = _url; - } public void execute(){ @@ -39,8 +37,8 @@ public void execute(){ conn = cm.open(this.url); - int length = conn.getContentLength(); - + int length = conn.getContentLength(); + new DownloadThread(conn,0,length-1).start(); } catch (ConnectionException e) { diff --git a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java index 3057663d0a..18acf4f9d9 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java @@ -21,7 +21,7 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "http://localhost:8080/test.jpg"; + String url = "http://img.pconline.com.cn/images/upload/upc/tx/softbbs/1202/07/c0/10352440_1328580074622.jpg"; FileDownloader downloader = new FileDownloader(url); @@ -38,14 +38,14 @@ public void notifyFinished() { }); downloader.execute(); - + // 等待多线程下载程序执行完毕 while (!downloadFinished) { try { System.out.println("还没有下载完成,休眠五秒"); //休眠5秒 Thread.sleep(5000); - } catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java b/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java index d4f61f719c..e8fac91d1e 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/api/ConnectionException.java @@ -2,4 +2,7 @@ public class ConnectionException extends Exception { + public ConnectionException(String msg){ + super(msg); + } } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java index 93239c6503..3d2e8de427 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java @@ -1,20 +1,88 @@ package thread.download.impl; import thread.download.api.Connection; +import thread.download.api.ConnectionException; import java.io.IOException; +import java.io.InputStream; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.URL; -public class ConnectionImpl implements Connection{ +public class ConnectionImpl implements Connection { - public byte[] read(int startPos, int endPos) throws IOException { - return new byte[0]; - } + private int length = 0; - public int getContentLength() { - return 0; - } + private URL url; - public void close() { + private HttpURLConnection conn; - } + + private InputStream is; + + + private ConnectionImpl() { + } + + public ConnectionImpl(URL url) { + this.url = url; + try { + this.conn = (HttpURLConnection) url.openConnection(); + this.conn.setRequestMethod("GET"); + this.conn.setReadTimeout(5000); + int responseCode = this.conn.getResponseCode(); + System.out.println("连接状态=" + responseCode); + if (responseCode != 200) { + throw new ConnectionException("连接到" + url.toURI() + "失败"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public byte[] read(int startPos, int endPos) throws IOException { + try { + //设置读取段落 + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + //获取返回值 + int response = conn.getResponseCode(); + if(response != 200 || response != 206){ + throw new ConnectException("没有连接上" + url.toURI() + ", 状态码为" + response); + } + + //开始读取 + int length = endPos - startPos; + this.is = conn.getInputStream(); + byte[] buffer = new byte[length]; + is.read(buffer); + System.out.println(startPos + "-" + endPos + "文件段读取完成"); + return buffer; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + this.close(); + } + } + + public int getContentLength() { + try { + this.length = this.conn.getContentLength(); + System.out.println("获取的文件长度=" + length); + return this.length; + } catch (Exception e) { + e.printStackTrace(); + return -1; + } + } + + public void close() { + try { + if(is != null){ + is.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java index 2eb0c784ec..ede8ccac00 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionManagerImpl.java @@ -1,13 +1,20 @@ package thread.download.impl; - import thread.download.api.Connection; import thread.download.api.ConnectionException; import thread.download.api.ConnectionManager; +import java.net.URL; + public class ConnectionManagerImpl implements ConnectionManager { public Connection open(String url) throws ConnectionException { - return null; + Connection conn = null; + try{ + conn = new ConnectionImpl(new URL(url)); + }catch(Exception e){ + e.printStackTrace(); + } + return conn; } } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java new file mode 100644 index 0000000000..6e92dadfb7 --- /dev/null +++ b/group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java @@ -0,0 +1,13 @@ +package thread.download.impl; + +import thread.download.api.DownloadListener; + +/** + * @author : 温友朝 + * @date : 2017/4/13 + */ +public class DownLoadListenerImpl implements DownloadListener { + public void notifyFinished() { + + } +} From c25af036933400acfad909bb8b43e66a2a79fc7c Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Fri, 14 Apr 2017 00:42:59 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E4=BD=9C=E4=B8=9A=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/thread/download/DownloadThread.java | 20 +++++- .../java/thread/download/FileDownloader.java | 65 +++++++++++++++---- .../thread/download/FileDownloaderTest.java | 8 +-- .../thread/download/api/DownloadListener.java | 2 +- .../thread/download/impl/ConnectionImpl.java | 25 ++++--- .../download/impl/DownLoadListenerImpl.java | 13 ---- 6 files changed, 89 insertions(+), 44 deletions(-) delete mode 100644 group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java diff --git a/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java b/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java index a868f6b5bb..190cae6423 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/DownloadThread.java @@ -3,21 +3,35 @@ import thread.download.api.Connection; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + public class DownloadThread extends Thread{ Connection conn; int startPos; int endPos; - public DownloadThread( Connection conn, int startPos, int endPos){ - + String localFile = ""; + + CyclicBarrier barrier; + + public DownloadThread(Connection conn, int startPos, int endPos, String localFileName, CyclicBarrier barrier){ + this.localFile = localFileName; this.conn = conn; this.startPos = startPos; this.endPos = endPos; + this.barrier = barrier; } public void run(){ try{ - this.conn.read(this.startPos, this.endPos); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + byte[] buffer = this.conn.read(this.startPos, this.endPos); + file.seek(startPos); + file.write(buffer); + file.close(); + this.conn.close(); + barrier.await(); }catch(Exception e){ e.printStackTrace(); } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java index 20084d4ddd..f50560b8be 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloader.java @@ -1,21 +1,30 @@ package thread.download; import thread.download.api.Connection; -import thread.download.api.ConnectionException; import thread.download.api.ConnectionManager; import thread.download.api.DownloadListener; +import java.io.File; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + public class FileDownloader { String url; - + String fileLocation; DownloadListener listener; - ConnectionManager cm; - - public FileDownloader(String _url) { + RandomAccessFile file; + + int length; + + private static final int MAX_THREAD_NUM = 5; + + + public FileDownloader(String _url, String fileLocation) { this.url = _url; + this.fileLocation = fileLocation; } public void execute(){ @@ -33,15 +42,34 @@ public void execute(){ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 Connection conn = null; + try { - + CyclicBarrier barrier = new CyclicBarrier(MAX_THREAD_NUM, new Runnable() { + public void run() { + listener.notifyFinished(); + } + }); + conn = cm.open(this.url); - - int length = conn.getContentLength(); + this.length = conn.getContentLength(); + + file = getEmptyFile(); - new DownloadThread(conn,0,length-1).start(); - - } catch (ConnectionException e) { + int divided = length/MAX_THREAD_NUM; + int[] pos = new int[MAX_THREAD_NUM + 1]; + for(int i = 0; i < MAX_THREAD_NUM; i++){ + pos[i] = i == 0 ? 0 : divided * i; + } + pos[MAX_THREAD_NUM] = length; + + for(int i = 0; i < MAX_THREAD_NUM; i++){ + new DownloadThread(conn, pos[i], pos[i + 1] - 1, this.fileLocation, barrier).start(); + } + + + File file2 = new File(fileLocation); + System.out.println("file.length=" + file2.length()); + } catch (Exception e) { e.printStackTrace(); }finally{ if(conn != null){ @@ -49,7 +77,20 @@ public void execute(){ } } } - + + public RandomAccessFile getEmptyFile(){ + try{ + RandomAccessFile file = new RandomAccessFile(this.fileLocation, "rw"); + byte[] empty = new byte[this.length]; + file.write(empty); + file.close(); + return file; + }catch(Exception e){ + e.printStackTrace(); + } + return null; + } + public void setListener(DownloadListener listener) { this.listener = listener; } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java index 18acf4f9d9..79752045f8 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java @@ -21,16 +21,14 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "http://img.pconline.com.cn/images/upload/upc/tx/softbbs/1202/07/c0/10352440_1328580074622.jpg"; - - FileDownloader downloader = new FileDownloader(url); + String url = "https://www.baidu.com/img/bd_logo1.png"; + String fileLocation = "D:\\Tee\\JavaLearnin\\test.png"; + FileDownloader downloader = new FileDownloader(url, fileLocation); - ConnectionManager cm = new ConnectionManagerImpl(); downloader.setConnectionManager(cm); downloader.setListener(new DownloadListener() { - public void notifyFinished() { downloadFinished = true; } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java b/group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java index f5cf47d886..16393c4dd9 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/api/DownloadListener.java @@ -1,5 +1,5 @@ package thread.download.api; public interface DownloadListener { - public void notifyFinished(); + void notifyFinished(); } diff --git a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java index 3d2e8de427..2e2544ab27 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java +++ b/group24/75939388/learning2017/src/main/java/thread/download/impl/ConnectionImpl.java @@ -3,6 +3,7 @@ import thread.download.api.Connection; import thread.download.api.ConnectionException; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ConnectException; @@ -17,12 +18,11 @@ public class ConnectionImpl implements Connection { private HttpURLConnection conn; - private InputStream is; + private ByteArrayOutputStream baos; - private ConnectionImpl() { - } + private ConnectionImpl() {} public ConnectionImpl(URL url) { this.url = url; @@ -43,20 +43,25 @@ public ConnectionImpl(URL url) { public byte[] read(int startPos, int endPos) throws IOException { try { //设置读取段落 - conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + this.conn = (HttpURLConnection) url.openConnection(); + this.conn.setRequestMethod("GET"); + this.conn.setReadTimeout(5000); + this.conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); //获取返回值 int response = conn.getResponseCode(); - if(response != 200 || response != 206){ + if(response != 200 && response != 206){ throw new ConnectException("没有连接上" + url.toURI() + ", 状态码为" + response); } - //开始读取 - int length = endPos - startPos; + int length = endPos - startPos + 1; this.is = conn.getInputStream(); - byte[] buffer = new byte[length]; - is.read(buffer); + byte[] buffer = new byte[1024]; + baos = new ByteArrayOutputStream(length); + while(-1 != is.read(buffer)){ + baos.write(buffer); + } System.out.println(startPos + "-" + endPos + "文件段读取完成"); - return buffer; + return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); return null; diff --git a/group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java b/group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java deleted file mode 100644 index 6e92dadfb7..0000000000 --- a/group24/75939388/learning2017/src/main/java/thread/download/impl/DownLoadListenerImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package thread.download.impl; - -import thread.download.api.DownloadListener; - -/** - * @author : 温友朝 - * @date : 2017/4/13 - */ -public class DownLoadListenerImpl implements DownloadListener { - public void notifyFinished() { - - } -} From a8f75239cd552f33f10a4709c522db699e7d58f1 Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Fri, 14 Apr 2017 17:23:19 +0800 Subject: [PATCH 18/19] =?UTF-8?q?test=E6=96=87=E4=BB=B6=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/thread => test/java}/download/FileDownloaderTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename group24/75939388/learning2017/src/{main/java/thread => test/java}/download/FileDownloaderTest.java (95%) diff --git a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java b/group24/75939388/learning2017/src/test/java/download/FileDownloaderTest.java similarity index 95% rename from group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java rename to group24/75939388/learning2017/src/test/java/download/FileDownloaderTest.java index 79752045f8..0dc8536269 100644 --- a/group24/75939388/learning2017/src/main/java/thread/download/FileDownloaderTest.java +++ b/group24/75939388/learning2017/src/test/java/download/FileDownloaderTest.java @@ -1,8 +1,9 @@ -package thread.download; +package download; import org.junit.After; import org.junit.Before; import org.junit.Test; +import thread.download.FileDownloader; import thread.download.api.ConnectionManager; import thread.download.api.DownloadListener; import thread.download.impl.ConnectionManagerImpl; From e4987a1974ae38bd284a9058320a90a1a52fe9dc Mon Sep 17 00:00:00 2001 From: macvis_qq75939388 Date: Sun, 16 Apr 2017 21:46:31 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../week01/BasicDataStructure/ArrayList.java | 75 - .../BasicDataStructure/BinaryTreeNode.java | 56 - .../week01/BasicDataStructure/LinkedList.java | 113 -- .../src/week01/BasicDataStructure/Queue.java | 25 - .../src/week01/BasicDataStructure/Stack.java | 25 - .../BasicDataStructureTest/AllTest.java | 18 - .../BasicDataStructureTest/ArrayListTest.java | 72 - .../BinaryTreeNodeTest.java | 80 - .../LinkedListTest.java | 106 -- .../BasicDataStructureTest/QueueTest.java | 56 - .../BasicDataStructureTest/StackTest.java | 71 - .../week04/jvm/loader/ClassFileLoader.java | 52 + .../week04/jvm/test/ClassFileloaderTest.java | 85 ++ .../src/week04/jvm/test/EmployeeV1.java | 28 + .../zhouhui/src/week04/lru/LRUPageFrame.java | 110 ++ .../src/week04/lru/LRUPageFrameTest.java | 31 + .../week4/jvm/loader/ClassFileLoader.java | 74 + .../coding2017/week4/jvm/test/EmployeeV1.java | 30 + .../coding2017/week4/lru/LRUPageFrame.java | 131 ++ .../week4/jvm/loader/ClassFileLoaderTest.java | 81 ++ .../week4/lru/LRUPageFrameTest.java | 34 + group01/378213871/.classpath | 2 +- .../coderising/week03/basic/LinkedList.java | 390 +++++ .../coderising/week03/basic/LinkedListEx.java | 250 ++++ .../week03/basic/LinkedListTest.java | 202 +++ .../week03/download/DownloadThread.java | 48 + .../week03/download/FileDownloader.java | 129 ++ .../week03/download/FileDownloaderTest.java | 59 + .../week03/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 8 + .../download/api/ConnectionManager.java | 10 + .../download}/api/DownloadListener.java | 2 +- .../week03/download/impl/ConnectionImpl.java | 82 ++ .../download/impl/ConnectionManagerImpl.java | 15 + .../week03/download/test/ConnectionTest.java | 53 + .../jvm/loader/ClassFileLoader.java | 72 + .../jvm/test/ClassFileloaderTest.java | 90 ++ .../coderising/jvm/test/EmployeeV1.java | 31 + .../coderising/linklist/LRUPageFrame.java | 177 +++ .../coderising/linklist/LRUPageFrameTest.java | 30 + .../src/download/api/DownloadListener.java | 8 - .../src/download/impl/ConnectionImpl.java | 59 - .../895457260/code/src/litestruts/struts.xml | 11 - .../{ => main/java}/algorithm/ArrayUtil.java | 0 .../main/java/algorithm/lru/LRUPageFrame.java | 112 ++ .../java}/datastructure/basic/ArrayList.java | 0 .../datastructure/basic/BinarySortedTree.java | 0 .../datastructure/basic/BinaryTreeNode.java | 0 .../java}/datastructure/basic/Iterator.java | 0 .../java}/datastructure/basic/LinkedList.java | 0 .../java}/datastructure/basic/List.java | 0 .../java}/datastructure/basic/Queue.java | 0 .../java}/datastructure/basic/Stack.java | 0 .../exception/EmptyListException.java | 0 .../exception/EmptyQueueException.java | 0 .../src/{ => main/java}/download/Config.java | 6 + .../java}/download/DownloadThread.java | 65 +- .../java}/download/FileDownloader.java | 82 +- .../main/java/download/api/Connection.java | 27 + .../download/api/ConnectionException.java | 0 .../java/download/api/ConnectionManager.java | 13 + .../java/download/api/DownloadCallback.java | 30 + .../java}/download/api/DownloadException.java | 0 .../java/download/api/OnCompleteListener.java | 12 + .../java/download/api/OnFailListener.java | 12 + .../java/download/impl/BaseConnection.java | 76 + .../download/impl/ConnectionManagerImpl.java | 29 + .../java/download/impl/DefaultConnection.java | 28 + .../java/download/impl/HttpConnection.java | 20 + .../java/download/impl/HttpsConnection.java | 24 + .../src/main/java/jvm/ClassFileLoader.java | 80 + .../code/src/main/java/jvm/LiteJvm.java | 25 + .../exception/ClassDuplicateException.java | 7 + .../exception/ClassNotExistsException.java | 7 + .../jvm/exception/MagicNumberException.java | 7 + .../jvm/exception/ReadClassException.java | 7 + .../src/main/java/jvm/util/ArrayUtils.java | 31 + .../{ => main/java}/litestruts/Struts.java | 0 .../src/{ => main/java}/litestruts/View.java | 0 .../java}/litestruts/action/LoginAction.java | 0 .../XmlElementNotFoundException.java | 0 .../java/algorithm}/ArrayUtilTest.java | 2 +- .../java/algorithm/lru/LRUPageFrameTest.java | 31 + .../java/datastructure}/ArrayListTest.java | 2 +- .../datastructure}/BinarySortedTreeTest.java | 2 +- .../java/datastructure}/LinkedListTest.java | 2 +- .../java/datastructure}/QueueTest.java | 2 +- .../java/datastructure}/StackTest.java | 2 +- .../java/datastructure}/TestSuite.java | 2 +- .../java/download/FileDownloaderTest.java | 87 ++ .../test/java/jvm/ClassFileLoaderTest.java | 61 + .../code/src/test/java/jvm/EmployeeV1.java | 29 + .../code/src/test/java/jvm/LiteJvmTest.java | 83 ++ .../java/litestruts}/StrutsTest.java | 2 +- .../coderising/download/DownloadThread.java | 27 +- .../coderising/download/FileDownloader.java | 58 +- .../download/FileDownloaderTest.java | 15 +- .../download/api/ConnectionException.java | 14 +- .../download/impl/ConnectionImpl.java | 51 +- .../download/impl/ConnectionManagerImpl.java | 10 +- .../aaront/exercise/basic/LRUPageFrame.java | 117 ++ .../execrise/basic/LRUPageFrameTest.java | 32 + .../com/aaront/exercise/DownloadThread.java | 14 +- .../com/aaront/exercise/FileDownloader.java | 11 - .../aaront/exercise/FileDownloaderTest.java | 3 +- .../aaront/exercise/impl/ConnectionImpl.java | 33 +- .../exercise/impl/ConnectionManagerImpl.java | 15 +- .../src/main/resources/test.jpg | Bin 20442 -> 0 bytes .../exercise/jvm/loader/ClassFileLoader.java | 64 + .../exercise/jvm/loader/EmployeeV1.java | 28 + .../exercise/jvm/utils/string/FileUtils.java | 16 + .../jvm/utils/string/StringUtils.java | 40 + .../jvm/loader/ClassFileLoaderTest.java | 77 + .../download/DownloadThread.java | 37 + .../download/FileDownloader.java | 112 ++ .../download/FileDownloaderTest.java | 60 + .../download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 75 + .../download/impl/ConnectionManagerImpl.java | 15 + .../fei9009/coding2017/basic/LinkedList.java | 131 ++ .../coding2017/basic/LinkedListTest.java | 312 +++- .../fei9009/coding2017/basic/ListTest.java | 93 ++ group02/812350401/.gitignore | 7 +- .../coderising/litestruts/struts.xml | 11 - .../coding2017/basic/ArrayList.java | 156 +- .../coding2017/basic/BinaryTreeNode.java | 110 +- .../miniyk2012/coding2017/basic/Iterator.java | 12 +- .../coding2017/basic/IteratorImp.java | 0 .../coding2017/basic/LinkedList.java | 730 +++++----- .../miniyk2012/coding2017/basic/List.java | 20 +- .../miniyk2012/coding2017/basic/Queue.java | 46 +- .../miniyk2012/coding2017/basic/Stack.java | 50 +- .../coderising/array/ArrayUtil.java | 558 +++---- .../coderising/download/DownloadThread.java | 92 +- .../coderising/download/FileDownloader.java | 236 +-- .../coderising/download/api/Connection.java | 48 +- .../download/api/ConnectionException.java | 10 +- .../download/api/ConnectionManager.java | 26 +- .../download/api/DownloadListener.java | 10 +- .../download/impl/ConnectionImpl.java | 128 +- .../download/impl/ConnectionManagerImpl.java | 46 +- .../coderising/litestruts/LoginAction.java | 96 +- .../coderising/litestruts/LogoutAction.java | 96 +- .../coderising/litestruts/Struts.java | 346 ++--- .../coderising/litestruts/View.java | 54 +- .../src/{ => main/java}/utils/ArrayUtils.java | 0 .../coding2017/basic}/ArrayListTest.java | 3 +- .../coding2017/basic}/BinaryTreeNodeTest.java | 2 +- .../coding2017/basic}/LinkedListTest.java | 5 +- .../coding2017/basic}/ListTest.java | 2 +- .../coding2017/basic}/QueueTest.java | 2 +- .../coding2017/basic}/StackTest.java | 2 +- .../coderising/array}/ArrayUtilTest.java | 2 +- .../download}/ConnectionImplTest.java | 9 +- .../download/FileDownloaderTest.java | 110 +- .../coderising/litestruts/StrutsTest.java | 147 +- .../download/api/ConnectionException.java" | 8 + .../src/download/api/DownloadListener.java" | 1 + .../jobs3/download/DownloadThread.java | 24 +- .../jobs3/download/FileDownloader.java | 137 +- .../jobs3/download/api/ConnectionManager.java | 5 +- .../jobs3/download/impl/ConnectionImpl.java | 65 +- .../download/impl/ConnectionManagerImpl.java | 8 +- .../{ => download}/FileDownloaderTest.java | 10 +- .../download/impl/ConnectionImplTest.java | 39 + .../coderising/download/DownloadThread.java | 47 + .../coderising/download/FileDownloader.java | 157 ++ .../coderising/download/api/Connection.java | 23 + .../download}/api/ConnectionException.java | 4 +- .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 59 + .../download/impl/ConnectionManagerImpl.java | 29 + .../main/java/com/coding/basic/ArrayList.java | 32 + .../com/coding/basic/BinaryTreeNode.java | 0 .../main/java}/com/coding/basic/Iterator.java | 0 .../java/com/coding/basic/LinkedList.java | 392 +++++ .../src/main/java}/com/coding/basic/List.java | 0 .../src/main/java/com/coding/basic/Queue.java | 19 + .../src/main/java/com/coding/basic/Stack.java | 22 + .../coderising/download/ConnectionTest.java | 20 + .../download/FileDownloaderTest.java | 42 + .../coderising/download/TestLinkedList.java | 245 ++++ group03/345943980/lite-struts-0226/pom.xml | 6 + .../teacher/litestruts/Configuration.java | 105 ++ .../litestruts/ConfigurationException.java | 23 + .../teacher/litestruts/LoginAction.java | 41 + .../teacher/litestruts/ReflectionUtil.java | 72 + .../coderising/teacher/litestruts/Struts.java | 52 + .../coderising/teacher/litestruts/View.java | 26 + .../litestruts/ConfigurationTest.java | 36 + .../litestruts/ReflectionUtilTest.java | 100 ++ .../com/coderising/litestruts/StrutsTest.java | 40 +- .../coderising/litestruts/StrutsTest1.java | 38 + .../com/circle/collection/LinkedListV2.java | 414 ++++++ .../com/circle/download/DownloadThread.java | 54 + .../com/circle/download/FileDownloader.java | 106 ++ .../com/circle/download/api/Connection.java | 31 + .../download/api/ConnectionException.java | 24 + .../download/api/ConnectionManager.java | 12 + .../circle/download/api/DownloadListener.java | 8 + .../circle/download/impl/ConnectionImpl.java | 77 + .../impl/ConnectionManagerFactory.java | 31 + .../download/impl/ConnectionManagerImpl.java | 31 + .../circle/collection/LinkedListV2Test.java | 245 ++++ .../circle/download/FileDownloaderTest.java | 49 + .../619224754/src/com/coderising/lru/LRU.java | 75 + .../src/com/coding/basic/Dequeue.java | 32 + group03/619224754/src/test/LRUTest.java | 23 + .../src/com/ace/coding/LinkedList.java | 194 ++- .../src/com/ace/coding/LinkedListTest.java | 33 + .../src/com/ace/download/DownloadThread.java | 46 + .../src/com/ace/download/FileDownloader.java | 99 ++ .../src/com/ace/download/api/Connection.java | 23 + .../ace/download/api/ConnectionException.java | 5 + .../ace/download/api/ConnectionManager.java | 13 + .../ace/download/api/DownloadListener.java | 5 + .../com/ace/download/impl/ConnectionImpl.java | 57 + .../download/impl/ConnectionManagerImpl.java | 28 + .../src/com/ace/homework2/Struts.java | 25 +- .../1020483199/1020483199Learning/.classpath | 2 +- .../jvm/loader/ClassFileLoader.java | 92 ++ .../jvm/test/ClassFileloaderTest.java | 91 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../coding/basic/linkedList}/Iterator.java | 2 +- .../coding/basic/linkedList/LRUPageFrame.java | 141 ++ .../basic/linkedList/LRUPageFrameTest.java | 32 + .../coding/basic/linkedList/LinkedList.java | 374 +++++ .../src/com/coding/basic/linkedList/List.java | 9 + .../src/com/coderising/array/ArrayUtil.java | 96 ++ .../coderising/download/DownloadThread.java | 42 + .../coderising/download/FileDownloader.java | 139 ++ .../download/FileDownloaderTest.java | 90 ++ .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 13 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 6 + .../download/impl/ConnectionImpl.java | 89 ++ .../download/impl/ConnectionManagerImpl.java | 17 + .../coderising/litestruts/LoginAction.java | 0 .../src/com/coderising/litestruts/Struts.java | 37 + .../com/coderising/litestruts/StrutsTest.java | 0 .../src/com/coderising/litestruts/View.java | 27 + .../src/com/coding/basic/ArrayList.java | 32 + .../src/com/coding/basic/BinaryTreeNode.java | 0 .../src/com/coding/basic/Iterator.java | 0 .../src/com/coding/basic/LinkedList.java | 374 +++++ .../src/com/coding/basic/List.java | 0 .../src/com/coding/basic/Queue.java | 19 + .../src/com/coding/basic/Stack.java | 22 + group04/120549547/base/buil.bat | 5 - .../base/src/com/coding/basic/ArrayList.java | 93 -- .../base/src/com/coding/basic/LinkedList.java | 127 -- .../base/src/com/coding/basic/Main.java | 85 -- .../base/src/com/coding/basic/Queue.java | 29 - .../base/src/com/coding/basic/Stack.java | 37 - .../java/com/coding/basic/BinaryTreeNode.java | 32 + .../main/java/com/coding/basic/Iterator.java | 8 + .../src/main/java/com/coding/basic/List.java | 31 + .../main/java}/com/coding/basic/Stack.java | 0 .../com/coding/basic/array/ArrayList.java | 155 ++ .../com/coding/basic/array/ArrayUtil.java | 269 ++++ .../coding/basic/linklist/LRUPageFrame.java | 60 + .../basic/linklist/LRUPageFrameTest.java | 31 + .../com/coding/basic/linklist/LinkedList.java | 369 +++++ .../com/coding/basic/queue/ArrayQueue.java | 97 ++ .../java/com/coding/basic/queue/Queue.java | 16 + .../com/coding/download/DownloadThread.java | 21 + .../com/coding/download/FileDownloader.java | 73 + .../coding/download/FileDownloaderTest.java | 59 + .../com/coding/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../coding/download/api/DownloadListener.java | 5 + .../coding/download/impl/ConnectionImpl.java | 28 + .../download/impl/ConnectionManagerImpl.java | 16 + .../com/coding/litestruts/Configuration.java | 124 ++ .../com/coding/litestruts/LoginAction.java | 39 + .../com/coding/litestruts/ReflectionUtil.java | 85 ++ .../java/com/coding/litestruts/Struts.java | 67 + .../com/coding/litestruts/StrutsTest.java | 47 + .../main/java/com/coding/litestruts/View.java | 23 + .../com/coding/basic/array/ArrayListTest.java | 122 ++ .../com/coding/basic/array/ArrayUtilTest.java | 94 ++ .../coding/basic/linklist/LinkedListTest.java | 155 ++ .../coding/basic/queue/ArrayQueueTest.java | 68 + .../coding/litestruts/ConfigurationTest.java | 45 + .../coding/litestruts/ReflectionUtilTest.java | 124 ++ group04/120549547/my.txt | 1 - .../coderising/download/DownloadThread.java | 38 + .../coderising/download/FileDownloader.java | 83 ++ .../download/impl/ConnectionImpl.java | 59 + .../download/impl/ConnectionManagerImpl.java | 31 + .../jvm/loader/ClassFileLoader.java | 56 + .../src/com/coding/basic/LinkedList.java | 281 ++++ .../coding/basic/linklist/LRUPageFrame.java | 136 ++ .../basic/linklist/LRUPageFrameTest.java | 73 + group04/1796244932/learn01/1.png | Bin 0 -> 281 bytes group04/1796244932/learn01/pom.xml | 26 +- .../com/dudy/learn01/base/MyLinkedList.java | 119 +- .../singleton/EnumSingleton.java | 40 + .../singleton/SingletonDemo1.java | 66 + .../singleton/StaticClassInnerSingleton.java | 63 + .../dudy/learn01/download/DownloadThread.java | 59 + .../dudy/learn01/download/FileDownloader.java | 93 ++ .../dudy/learn01/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 13 + .../download/api/DownloadListener.java | 5 + .../learn01/download/impl/ConnectionImpl.java | 89 ++ .../download/impl/ConnectionManagerImpl.java | 25 + .../com/dudy/learn01/juc/ThreadLocalTest.java | 64 + .../com/dudy/learn01/litestruts/Struts.java | 1 + .../litestruts/format/Configuration.java | 113 ++ .../format/ConfigurationException.java | 21 + .../litestruts/format/ConfigurationTest.java | 50 + .../litestruts/format/LoginAction.java | 39 + .../litestruts/format/ReflectionUtil.java | 123 ++ .../litestruts/format/ReflectionUtilTest.java | 113 ++ .../learn01/litestruts/format/Struts.java | 68 + .../learn01/litestruts/format/StrutsTest.java | 43 + .../dudy/learn01/litestruts/format/View.java | 23 + .../com/dudy/learn01/utils/ArraySortDemo.java | 104 ++ .../dudy/learn01/base/MyLinkedListTest.java | 59 + .../learn01/download/FileDownloaderTest.java | 53 + group04/349184132/Study/.classpath | 8 - .../.settings/org.eclipse.jdt.core.prefs | 12 - .../349184132/Study/bin/com/second/struts.xml | 11 - .../349184132/Study/bin/com/test/student2.xml | 6 - .../349184132/Study/bin/com/test/students.xml | 10 - .../coderising/download/DownloadThread.java | 49 + .../coderising/download/FileDownloader.java | 112 ++ .../download/FileDownloaderTest.java | 58 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 10 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 52 + .../download/impl/ConnectionManagerImpl.java | 37 + .../Study/src/com/linked/Iterator.java | 7 + .../Study/src/com/linked/LinkedList.java | 388 +++++ .../349184132/Study/src/com/linked/List.java | 32 + .../src/com/second/Array/ArrayUtilTest.java | 2 +- .../com/coding/download/DownloadThread.java | 34 + .../com/coding/download/FileDownloader.java | 76 + .../coding/download/FileDownloaderTest.java | 59 + .../com/coding/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 10 + .../download/api/ConnectionManager.java | 10 + .../coding/download/api/DownloadListener.java | 5 + .../coding/download/impl/ConnectionImpl.java | 50 + .../download/impl/ConnectionManagerImpl.java | 23 + group04/474772605/.classpath | 4 + group04/474772605/jsp/homepage.jsp | 12 + group04/474772605/jsp/showLogin.jsp | 12 + .../com/coderising/action/LoginAction.java | 79 +- .../com/coderising/action/LogoutAction.java | 40 + .../src/com/coderising/action/Struts.java | 122 ++ .../src/com/coderising/action/StrutsTest.java | 43 + .../src/com/coderising/action/View.java | 23 + .../src/com/coderising/array/ArrayUtil.java | 146 ++ .../src/com/coding/basic/LinkedList.java | 1 + .../474772605/src/com/coding/basic/List.java | 2 +- .../474772605/src/com/coding/basic/Node.java | 12 + .../474772605/src/com/coding/basic/Stack.java | 34 +- .../com/coding/basic/Testclassextends.java | 17 + .../src/com/coding/basic/testarraylist.java | 7 +- .../src/com/coding/iostreams/inteface.java | 11 + .../src/com/coding/iostreams/readfile.java | 67 + .../src/com/coding/iostreams/test.java | 14 + group04/474772605/test/Test.java | 50 + .../test/com/coding/basic/Heros.java | 51 + .../474772605/test/com/coding/basic/Test.java | 43 + .../test/com/coding/basic/TestStack.java | 35 + .../test/com/coding/basic/Testarray.java | 22 + .../test/com/coding/basic/teest.java | 24 + .../jvm/loader/ClassFileLoader.java | 83 ++ .../jvm/test/ClassFileloaderTest.java | 93 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../src/org/coding/four/lru/LRUPageFrame.java | 134 ++ .../one/src/org/coding/one/LinkedList.java | 3 + .../coding/three/download/DownloadThread.java | 36 + .../coding/three/download/FileDownloader.java | 108 ++ .../coding/three/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 16 + .../three/download/api/ConnectionManager.java | 10 + .../three/download/api/DownloadListener.java | 5 + .../three/download/impl/ConnectionImpl.java | 67 + .../download/impl/ConnectionManagerImpl.java | 14 + .../one/src/org/coding/three/list}/List.java | 2 +- .../coding/three/list/impl/LinkedList.java | 422 ++++++ .../org/coding/four/lru/LRUPageFrameTest.java | 31 + .../three/download/FileDownloaderTest.java | 61 + .../three/list/impl/LinkedListTest.java | 477 ++++++ .../coderising/download/DownloadThread.java | 62 + .../coderising/download/FileDownloader.java | 115 ++ .../download/FileDownloaderTest.java | 58 + .../coderising/download/api/Connection.java | 29 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 11 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 87 ++ .../download/impl/ConnectionManagerImpl.java | 42 + .../main/java/com/coding/basic/ArrayList.java | 3 + .../java/com/coding/basic/LinkedList.java | 215 +++ .../java/com/coding/basic/TestLinkedList.java | 110 ++ .../src/test/java/com/txp/temp/Test.java | 9 + .../844028312/four/linklist/LRUPageFrame.java | 127 ++ .../four/linklist/LRUPageFrameTest.java | 31 + .../844028312/four/linklist/LinkedList.java | 125 ++ .../jvm/loader/ClassFileLoader.java | 92 ++ .../jvm/test/ClassFileloaderTest.java | 92 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../src/com/coderising/array/ArrayUtil.java | 96 ++ .../coderising/download/DownloadThread.java | 48 + .../coderising/download/FileDownloader.java | 86 ++ .../download/FileDownloaderTest.java | 115 ++ .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 54 + .../download/impl/ConnectionManagerImpl.java | 33 + .../coderising/litestruts/LoginAction.java | 0 .../src/com/coderising/litestruts/Struts.java | 37 + .../coderising}/litestruts/StrutsTest.java | 8 +- .../src/com/coderising/litestruts/View.java | 0 .../three/src/com/coding/basic/ArrayList.java | 32 + .../src/com/coding/basic/BinaryTreeNode.java | 32 + .../three}/src/com/coding/basic/Iterator.java | 0 .../src/com/coding/basic/LinkedList.java | 417 ++++++ .../src/com/coding/basic/LinkedListTest.java | 145 ++ .../three}/src/com/coding/basic/List.java | 0 .../three/src/com/coding/basic/Queue.java | 19 + .../three/src/com/coding/basic/Stack.java | 22 + .../src/com/coderising/array/ArrayUtil.java | 185 +-- .../com/coderising/array/ArrayUtilTest.java | 6 +- group04/916758663/learn01/learn01.iml | 2 +- .../main/java/com/coding/basic/ArrayList.java | 27 +- .../com/example/download/DownloadThread.java | 50 + .../com/example/download/FileDownloader.java | 76 + .../main/java/com/example/download/Utils.java | 24 + .../com/example/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../example/download/impl/ConnectionImpl.java | 58 + .../download/impl/ConnectionManagerImpl.java | 16 + .../example/download/FileDownloaderTest.java | 57 + .../java/com/example/download/UtilsTest.java | 31 + .../download/impl/ConnectionImplTest.java | 49 + .../example/jvm/loader/ClassFileLoader.java | 70 + .../jvm/loader/ClassFileLoaderTest.java | 78 + .../com/example/jvm/loader/EmployeeV1.java | 28 + .../jvm/loader/ClassFileLoader.java | 88 ++ .../jvm/test/ClassFileloaderTest.java | 95 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../src/com/coding/basic/QueueTest.java | 2 - .../src/com/coding/lru/LRUPageFrame.java | 129 ++ .../src/com/coding/lru/LRUPageFrameTest.java | 38 + .../jvm/loader/ClassFileLoader.java | 46 + .../jvm/test/ClassFileloaderTest.java | 74 + .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../src/com/coding2017/basic/Queue.java | 2 + .../basic/{ => array}/ArrayList.java | 0 .../basic}/array/ArrayUtil.java | 0 .../basic}/array/ArrayUtilTest.java | 0 .../basic/linklist/LRUPageFrame.java | 113 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../basic/{ => linklist}/LinkedList.java | 5 +- .../coderising/download/DownloadThread.java | 35 + .../coderising/download/FileDownloader.java | 104 ++ .../download/FileDownloaderTest.java | 56 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 46 + .../download/impl/ConnectionManagerImpl.java | 29 + .../src/com/coderising/litestruts/Struts.java | 19 +- group06/1378560653/.classpath | 1 + group06/1378560653/article.txt | 4 +- .../src/com/coderising/array/ArrayUtil.java | 212 --- .../coderising/download/DownloadThread.java | 40 + .../coderising/download/FileDownloader.java | 131 ++ .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 9 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 96 ++ .../download/impl/ConnectionManagerImpl.java | 15 + .../jvm/loader/ClassFileLoader.java | 61 + .../jvm/test/ClassFileloaderTest.java | 85 ++ .../com/coderising/jvm/test/EmployeeV1.java | 27 + .../coderising/litestruts/Configuration.java | 113 ++ .../litestruts/ConfigurationException.java | 21 + .../litestruts/ConfigurationTest.java | 50 + .../coderising/litestruts/LoginAction.java | 4 +- .../coderising/litestruts/ReflectionUtil.java | 123 ++ .../litestruts/ReflectionUtilTest.java | 111 ++ .../src/com/coderising/litestruts/Struts.java | 52 +- .../{StructsTest.java => StrutsTest.java} | 4 +- .../src/com/coderising/litestruts/structs.xml | 11 - .../src/com/coding/basic/Queue.java | 2 + .../src/com/coding/basic/Stack.java | 2 + .../coding/basic/{ => array}/ArrayList.java | 5 +- .../src/com/coding/basic/array/ArrayUtil.java | 262 ++++ .../com/coding/basic/array/ArrayUtilTest.java | 150 ++ .../coding/basic/linklist/LRUPageFrame.java | 154 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../com/coding/basic/linklist/LinkedList.java | 445 ++++++ .../coding/basic/linklist/LinkedListTest.java | 309 ++++ .../src/com/coding/basic/homework_04/jvm.rar | Bin 0 -> 2437 bytes .../jvm/loader/ClassFileLoader.java | 114 ++ .../jvm/test/ClassFileloaderTest.java | 89 ++ .../homework_04/jvm/test/EmployeeV1.java | 29 + .../basic/homework_04/lru/LRUPageFrame.java | 137 ++ .../homework_04/lru/LRUPageFrameTest.java | 31 + group06/2415980327/CodeSE01/down2.png | Bin 0 -> 398720 bytes .../src/com/pxshuo/se03/basic/LinkedList.java | 456 ++++++ .../src/com/pxshuo/se03/basic/List.java | 9 + .../pxshuo/se03/download/DownloadThread.java | 51 + .../pxshuo/se03/download/FileDownloader.java | 140 ++ .../se03/download/FileDownloaderTest.java | 64 + .../pxshuo/se03/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../se03/download/api/ConnectionManager.java | 10 + .../se03/download/api/DownloadListener.java | 5 + .../se03/download/impl/ConnectionImpl.java | 95 ++ .../download/impl/ConnectionManagerImpl.java | 14 + .../src/com/pxshuo/test/ConnectTest.java | 184 +++ .../CodeSE01/src/com/pxshuo/test/Test.java | 58 +- .../se03/array/LinkedListUntilTest.java | 144 ++ ...15\345\260\204\346\234\272\345\210\266.md" | 81 ++ ...\344\270\216\346\226\207\344\273\266IO.md" | 96 ++ .../learning/java/array/ArrayUtil.java | 6 +- .../java/collection/myown/MyLinkedList.java | 120 -- .../java/downloader/DownloadThread.java | 49 + .../java/downloader/FileDownloader.java | 90 ++ .../java/downloader/api/Connection.java | 23 + .../downloader/api/ConnectionException.java | 10 + .../downloader/api/ConnectionManager.java | 10 + .../java/downloader/api/DownloadListener.java | 5 + .../java/downloader/impl/ConnectionImpl.java | 73 + .../impl/ConnectionManagerImpl.java | 23 + .../learning/java/jvm/ClassFileLoader.java | 24 + .../java/linkedlist/LRUPageFrame.java | 151 ++ .../learning/java/linkedlist/LinkedList.java | 287 ++++ .../myown/MyStack.java => stack/Stack.java} | 6 +- .../learning/java/stack/StackUtil.java | 45 + .../collection/myown/MyLinkedListTest.java | 76 - .../java/collection/myown/MyStackTest.java | 8 +- .../java/downloader/FileDownloaderTest.java | 59 + .../java/jvm/ClassFileloaderTest.java | 76 + .../learning/java/jvm/EmployeeV1.java | 30 + .../java/linkedlist/LRUPageFrameTest.java | 33 + .../java/linkedlist/LinkedListTest.java | 239 +++ .../src/com/coderising/array/ArrayUtil.java | 163 +++ .../coderising/download/DownloadThread.java | 20 + .../coderising/download/FileDownloader.java | 73 + .../download/FileDownloaderTest.java | 0 .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 27 + .../download/impl/ConnectionManagerImpl.java | 15 + .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 34 + .../coderising/litestruts/StrutsTest.java | 8 +- .../src/com/coderising/litestruts/View.java | 0 .../Test/src/com/ecust/test/GArrayList.java | 148 ++ .../Test/src/com/ecust/test/GIterator.java | 6 + .../Test/src/com/ecust/test/GList.java | 18 + .../src/com/coding/basic/LinkedList.java | 382 ++++- .../homework/src/com/coding/basic/List.java | 17 + .../src/\346\226\207\347\253\240\344\270\211" | 1 + .../homework003/src/DownloadThread.java | 154 ++ .../homework003/src/FileDownloader.java | 158 ++ .../homework003/src/FileDownloaderTest.java | 107 ++ .../coderising/download/api/Connection.java | 63 + .../download/api/ConnectionException.java | 19 + .../download/api/ConnectionManager.java | 14 + .../download/api/DownloadListener.java | 7 + .../download/impl/ConnectionImpl.java | 186 +++ .../download/impl/ConnectionManagerImpl.java | 117 ++ .../coderising/litestruts/Configuration.java | 113 ++ .../litestruts/ConfigurationException.java | 21 + .../litestruts/ConfigurationTest.java | 50 + .../coderising/litestruts/LoginAction.java | 39 + .../coderising/litestruts/ReflectionUtil.java | 123 ++ .../litestruts/ReflectionUtilTest.java | 113 ++ .../src/com/coderising/litestruts/Struts.java | 171 +++ .../com/coderising/litestruts/StrutsTest.java | 43 + .../src/com/coderising/litestruts/View.java | 23 + ...4\260\345\235\200\346\261\207\346\200\273" | 1 + .../src/ClassFileLoader/ClassFileLoader.java | 88 ++ .../ClassFileLoader/ClassFileloaderTest.java | 5 + .../src/ClassFileLoader/EmployeeV1.java | 23 + .../src/ClassFileLoader/LRUPageFrame.java | 110 ++ .../src/Test/ClassFileloaderTest.java | 65 + .../homework04/src/Test/LRUPageFrameTest.java | 33 + .../homework04/src/\346\226\207\347\253\2404" | 1 + .../coderising/litestruts/Configuration.java | 113 ++ .../litestruts/ConfigurationException.java | 21 + .../litestruts/ConfigurationTest.java | 50 + .../coderising/litestruts/LoginAction.java | 39 + .../coderising/litestruts/ReflectionUtil.java | 123 ++ .../litestruts/ReflectionUtilTest.java | 113 ++ .../src/com/coderising/litestruts/Struts.java | 171 +++ .../com/coderising/litestruts/StrutsTest.java | 43 + .../src/com/coderising/litestruts/View.java | 23 + group08/1144989424/secondPractice/readme.md | 3 + group08/1144989424/thirdPractice/readme.md | 9 + .../src/download/DownloadThread.java | 26 + .../src/download/FileDownloader.java | 73 + .../src/download/FileDownloaderTest.java | 17 +- .../src/download/api/Connection.java | 23 + .../src/download/api/ConnectionException.java | 5 + .../src/download/api/ConnectionManager.java | 10 + .../src/download/api/DownloadListener.java | 5 + .../src/download/impl/ConnectionImpl.java | 39 + .../download/impl/ConnectionManagerImpl.java | 41 + .../download/impl/DownloadListenerImpl.java | 11 + .../src/linkedlist/MyIterator.java | 7 + .../src/linkedlist/MyLinkedList.java | 328 +++++ .../thirdPractice/src/linkedlist/MyList.java | 9 + .../1425809544/03-05/com/array/ArrayUtil.java | 257 ++++ .../03-05/com/array/ArrayUtilTest.java | 99 ++ ...0\345\231\250\347\273\223\346\236\204.txt" | 1 + .../code/com/xyy/baselinked/Iterator.java | 12 + .../code/com/xyy/baselinked/LinkedList.java | 372 +++++ .../03-12/code/com/xyy/baselinked/List.java | 17 + .../code/com/xyy/download/DownloadThread.java | 67 + .../code/com/xyy/download/FileDownloader.java | 116 ++ .../com/xyy/download/FileDownloaderTest.java | 53 + .../code/com/xyy/download/api/Connection.java | 32 + .../xyy/download/api/ConnectionException.java | 11 + .../xyy/download/api/ConnectionManager.java | 25 + .../xyy/download/api/DownloadListener.java | 9 + .../com/xyy/download/impl/ConnectionImpl.java | 120 ++ .../download/impl/ConnectionManagerImpl.java | 31 + ...32\345\256\242\345\234\260\345\235\200.md" | 1 + .../jvm/loader/ClassFileLoader.java | 48 + .../jvm/test/ClassFileloaderTest.java | 80 + .../com/coderising/jvm/test/EmployeeV1.java | 30 + .../coding/basic/linklist/LRUPageFrame.java | 142 ++ .../basic/linklist/LRUPageFrameTest.java | 29 + .../coding/basic/linklist/LRUPageFrame.java | 154 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../jvm/loader/ClassFileLoader.java | 87 ++ .../jvm/test/ClassFileloaderTest.java | 92 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + group08/README.md | 65 - ...\346\210\220\346\203\205\345\206\265.xlsx" | Bin 10920 -> 0 bytes .../2.code/jmr-01-aggregator/pom.xml | 9 +- .../data/shoppingcart/shoppingcart.data | Bin 0 -> 131 bytes .../classloader/core/NetworkClassLoader.java | 14 +- .../challenge/zzz/master170219/Try170205.java | 132 ++ .../challenge/zzz/master170219/Try170212.java | 34 + .../challenge/zzz/master170219/Try170219.java | 47 + .../com/hoo/download/BatchDownloadFile.java | 227 +++ .../java/com/hoo/download/DownloadFile.java | 176 +++ .../java/com/hoo/download/SaveItemFile.java | 68 + .../java/com/hoo/entity/DownloadInfo.java | 125 ++ .../main/java/com/hoo/util/DownloadUtils.java | 40 + .../java/com/hoo/util/DownloadUtilsTest.java | 39 + .../src/main/java/com/hoo/util/LogUtils.java | 40 + .../coderising/download}/api/Connection.java | 2 +- .../download/api/ConnectionException.java | 5 + .../download}/api/ConnectionManager.java | 2 +- .../download/api/DownloadListener.java | 5 + .../download/core/DownloadThread.java | 21 + .../download/core}/FileDownloader.java | 14 +- .../download}/impl/ConnectionImpl.java | 5 +- .../download/impl/ConnectionManagerImpl.java | 15 + .../jvm/loader/ClassFileLoader.java | 19 + .../coderising/litestruts}/LoginAction.java | 84 +- .../com/coderising/litestruts/Struts.java | 30 + .../java/com/coderising/litestruts}/View.java | 52 +- .../com/coding/basic}/BinaryTreeNode.java | 20 +- .../main/java}/com/coding/basic/Iterator.java | 3 +- .../src/main/java/com/coding/basic}/List.java | 2 +- .../src/main/java/com/coding/basic/Queue.java | 19 + .../src/main/java/com/coding/basic/Stack.java | 26 + .../com/coding/basic/array/ArrayList.java | 36 + .../com/coding/basic/array/ArrayUtil.java | 96 ++ .../coding/basic/linklist/LRUPageFrame.java | 50 + .../com/coding/basic/linklist/LinkedList.java | 129 ++ .../src/main/resources/.gitkeep | 0 .../download/core}/FileDownloaderTest.java | 13 +- .../jvm/loader/ClassFileloaderTest.java | 76 + .../com/coderising/jvm/loader/EmployeeV1.java | 30 + .../coderising/litestruts}/StrutsTest.java | 76 +- .../basic/linklist/LRUPageFrameTest.java | 27 + .../src/test/resources/.gitkeep | 0 .../java/com/coderising/basic/LinkedList.java | 449 ++++++ .../main/java/com/coderising/basic/List.java | 14 + .../coderising/download/api/Connection.java | 28 + .../download/api/ConnectionException.java | 8 + .../download/api/ConnectionManager.java | 11 + .../download/api/DownloadListener.java | 5 + .../download/core/DownloadThread.java | 50 + .../download/core/FileDownloader.java | 126 ++ .../download/impl/ConnectionImpl.java | 84 ++ .../download/impl/ConnectionManagerImpl.java | 15 + .../coderising/litestruts/Configuration.java | 113 ++ .../litestruts/ConfigurationException.java | 21 + .../coderising/litestruts/LoginAction.java | 42 + .../coderising/litestruts/ReflectionUtil.java | 120 ++ .../com/coderising/litestruts/Struts.java | 56 + .../java/com/coderising/litestruts/View.java | 26 + .../src/main/resources}/.gitkeep | 0 .../com/coderising/basic/LinkedListTest.java | 197 +++ .../download/api/ConnectionTest.java | 42 + .../download/core/FileDownloaderTest.java | 56 + .../litestruts/ConfigurationTest.java | 46 + .../litestruts/ReflectionUtilTest.java | 104 ++ .../com/coderising/litestruts/StrutsTest.java | 37 + .../src/test/resources}/.gitkeep | 0 .../2.code/jmr-61-170226-collection/pom.xml | 27 - .../src/main/resources/log4j.xml | 16 - .../jmr-61-170305-litestruts/data/struts.xml | 11 - .../2.code/jmr-61-170305-litestruts/pom.xml | 39 - .../src/main/resources/log4j.xml | 16 - .../jmr-61-170312-multiThreadDownload/pom.xml | 39 - .../multiDL/impl/ConnectionManagerImpl.java | 14 - .../src/main/resources/log4j.xml | 16 - .../eulerlcs/jmr/algorithm}/ArrayList.java | 2 +- .../src/main}/resources/.gitkeep | 0 .../jmr/algorithm}/TestArrayList.java | 4 +- .../src/test/resources}/.gitkeep | 0 .../src/main/java}/.gitkeep | 0 .../eulerlcs/jmr}/algorithm/ArrayUtil.java | 2 +- .../jmr/litestruts/action/LoginAction.java | 0 .../jmr/litestruts/action/LogoutAction.java | 0 .../eulerlcs/jmr/litestruts/core/Struts.java | 0 .../eulerlcs/jmr/litestruts/core/View.java | 0 .../jmr/litestruts/degister/StrutsAction.java | 0 .../degister/StrutsActionResult.java | 0 .../degister/StrutsActionRulerSet.java | 0 .../jmr/litestruts/degister/StrutsConfig.java | 0 .../litestruts/degister/StrutsDigester.java | 0 .../jmr-62-litestruts/src/test/java/.gitkeep | 0 .../jmr/algorithm}/ArrayUtilTest.java | 4 +- .../jmr/litestruts/core/StrutsTest.java | 0 .../src/test/resources/.gitkeep | 0 .../2.code/jmr-63-download/data/.gitkeep | 0 .../eulerlcs/jmr/algorithm/Iterator.java | 8 + .../eulerlcs/jmr/algorithm/LinkedList.java | 126 ++ .../github/eulerlcs/jmr/algorithm/List.java | 13 + .../eulerlcs/jmr/download/api/Connection.java | 28 + .../jmr/download/api/ConnectionException.java | 5 + .../jmr/download/api/ConnectionManager.java | 11 + .../jmr/download/api/DownloadListener.java | 5 + .../jmr/download/core}/DownloadThread.java | 4 +- .../jmr/download/core/FileDownloader.java | 64 + .../jmr/download/impl/ConnectionImpl.java | 25 + .../download/impl/ConnectionManagerImpl.java | 14 + .../jmr/download/core/FileDownloaderTest.java | 53 + .../src/test/resources/.gitkeep | 0 .../2.code/jmr-64-minijvm/data/.gitkeep | 0 .../eulerlcs/jmr/algorithm/LRUPageFrame.java | 110 ++ .../jmr/jvm/loader/ClassFileLoader.java | 66 + .../jmr/algorithm/LRUPageFrameTest.java | 27 + .../jmr/jvm/loader/ClassFileloaderTest.java | 53 + .../eulerlcs/jmr/jvm/loader/EmployeeV1.java | 28 + .../src/test/resources/.gitkeep | 0 .../5.settingfile/eclipsev45.epf | 186 +++ .../src/coding/week02/array/ArrayUtil.java | 345 +++++ .../coding/week02/array/ArrayUtilTest.java | 151 ++ .../src/coding/week03/DownloadThread.java | 39 + .../src/coding/week03/FileDownloader.java | 91 ++ .../week03/download/api/Connection.java | 28 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../week03/download/api/DownloadListener.java | 5 + .../week03/download/impl/ConnectionImpl.java | 49 + .../download/impl/ConnectionManagerImpl.java | 31 + .../coderising/download/DownloadThread.java | 56 +- .../coderising/download/FileDownloader.java | 163 ++- .../download/FileDownloaderTest.java | 26 +- .../coderising/download/api/Connection.java | 20 +- .../download/api/ConnectionException.java | 4 +- .../download/api/ConnectionManager.java | 9 +- .../download/api/DownloadListener.java | 4 +- .../download/impl/ConnectionImpl.java | 77 +- .../download/impl/ConnectionManagerImpl.java | 36 +- .../com/coderising/linkedlist}/Iterator.java | 2 +- .../com/coderising/linkedlist/LinkedList.java | 263 ++++ .../coderising/linkedlist/LinkedListTest.java | 170 +++ .../src/com/coderising/linkedlist/List.java | 9 + .../coderising/litestruts/Configuration.java | 113 ++ .../litestruts/ConfigurationException.java | 21 + .../litestruts/ConfigurationTest.java | 50 + .../coderising/litestruts/ReflectionUtil.java | 123 ++ .../litestruts/ReflectionUtilTest.java | 113 ++ .../src/com/coderising/litestruts/SAX.java | 30 - .../com/coderising/litestruts/SAXmain.java | 21 - .../src/com/coderising/litestruts/Struts.java | 57 +- group10/205301442/src/api/Connection.java | 23 + .../src/api/ConnectionException.java | 5 + .../205301442/src/api/ConnectionManager.java | 10 + .../205301442/src/api/DownloadListener.java | 6 + .../src/com/coding/week1/LinkedList1.java | 280 ++++ .../src/download/DownloadThread.java | 28 + .../src/download/FileDownloader.java | 157 ++ .../src/download/FileDownloaderTest.java | 50 + .../src/download/api/Connection.java | 23 + .../src/download/api/ConnectionException.java | 5 + .../src/download/api/ConnectionManager.java | 10 + .../src/download/api/DownloadListener.java | 6 + .../src/download/impl/ConnectionImpl.java | 76 + .../download/impl/ConnectionManagerImpl.java | 34 + .../src/download/impl/DoloadListenerImpl.java | 16 + .../205301442/src/impl/ConnectionImpl.java | 76 + .../src/impl/ConnectionManagerImpl.java | 34 + .../src/impl/DoloadListenerImpl.java | 16 + .../src/com/coding/basic/LRUPageFrame.java | 135 ++ .../com/coding/download/DownloadThread.java | 20 +- .../com/coding/download/FileDownloader.java | 50 +- .../download/api/ConnectionException.java | 5 + .../coding/download/impl/ConnectionImpl.java | 38 +- .../download/impl/ConnectionManagerImpl.java | 9 +- .../src/com/coding/litestruts/Action.java | 51 + .../src/com/coding/litestruts/Result.java | 42 + .../src/com/coding/litestruts/Struts.java | 72 +- .../coding/litestruts/StrutsXMLParser.java | 68 + .../com/coding/test/ClassFileloaderTest.java | 88 ++ .../src/com/coding/test/EmployeeV1.java | 29 + .../src/com/coding/test/LRUPageFrameTest.java | 32 + .../904627477/src/com/coding/test/Test.java | 48 +- .../src/com/coding/util/IOUtils.java | 30 + .../conding/jvm/loader/ClassFileLoader.java | 56 + .../coderising/download/DownloadThread.java | 42 +- .../coderising/download/FileDownloader.java | 36 +- .../com/coderising/download/NotifyCaller.java | 2 +- .../download/impl/ConnectionImpl.java | 36 +- .../jvm/loader/ClassFileLoader.java | 33 + .../jvm/loader/ClassFileLoaderUtil.java | 71 + .../src/com/coding/basic/BinaryTree.java | 2 + .../zj-2017/src/com/coding/basic/Queue.java | 2 + .../zj-2017/src/com/coding/basic/Stack.java | 2 + .../coding/basic/{ => array}/ArrayList.java | 201 +-- .../basic}/array/ArrayUtil.java | 495 ++++--- .../coding/basic/linklist/LRUPageFrame.java | 163 +++ .../basic/{ => linklist}/LinkedList.java | 543 +++---- .../jvm/loader/ClassFileloaderTest.java | 87 ++ .../com/coderising/jvm/loader/EmployeeV1.java | 28 + .../basic/{ => array}/ArrayListTest.java | 4 +- .../basic}/array/ArrayUtilTest.java | 240 +-- .../basic/linklist/LRUPageFrameTest.java | 31 + .../basic/{ => linklist}/LinkedListTest.java | 516 +++---- group12/247565311/week2/Struts.java | 2 +- group12/247565311/week3/DownloadThread.java | 38 +- group12/247565311/week3/FileDownloader.java | 29 +- .../247565311/week3/FileDownloaderTest.java | 19 +- .../247565311/week3/impl/ConnectionImpl.java | 58 +- .../week3/impl/ConnectionManagerImpl.java | 12 +- group12/247565311/week5/ClassFileLoader.java | 63 + .../247565311/week5/ClassFileLoaderTest.java | 72 + group12/247565311/week5/EmployeeV1.java | 5 + group12/247565311/week5/LRU.java | 67 + group12/247565311/week5/LRUTest.java | 36 + group12/349166103/LRUPageFrame.java | 108 ++ group12/377401843/learning/pom.xml | 11 + .../{collection => array}/ArrayList.java | 15 +- .../java/com/zhaogd/collection/Queue.java | 2 + .../collection/linkedlist/LRUPageFrame.java | 164 +++ .../linkedlist/LRUPageFrameTest.java | 34 + .../{ => linkedlist}/LinkedList.java | 13 +- .../zhaogd/collection/{ => stack}/Stack.java | 4 +- .../zhaogd/collection/stack/StackUtil.java | 45 + .../java/com/zhaogd/jvm/clz/AccessFlag.java | 25 + .../java/com/zhaogd/jvm/clz/ClassFile.java | 75 + .../java/com/zhaogd/jvm/clz/ClassIndex.java | 19 + .../com/zhaogd/jvm/constant/ClassInfo.java | 24 + .../com/zhaogd/jvm/constant/ConstantInfo.java | 29 + .../com/zhaogd/jvm/constant/ConstantPool.java | 29 + .../com/zhaogd/jvm/constant/FieldRefInfo.java | 54 + .../zhaogd/jvm/constant/MethodRefInfo.java | 55 + .../zhaogd/jvm/constant/NameAndTypeInfo.java | 45 + .../zhaogd/jvm/constant/NullConstantInfo.java | 13 + .../com/zhaogd/jvm/constant/StringInfo.java | 26 + .../com/zhaogd/jvm/constant/UTF8Info.java | 32 + .../zhaogd/jvm/loader/ByteCodeIterator.java | 5 + .../zhaogd/jvm/loader/ClassFileLoader.java | 140 ++ .../zhaogd/jvm/loader/ClassFileParser.java | 35 + .../zhaogd/jvm/test/ClassFileloaderTest.java | 202 +++ .../java/com/zhaogd/jvm/test/EmployeeV1.java | 28 + .../main/java/com/zhaogd/jvm/util/Util.java | 24 + .../com/zhaogd/collection/ArrayListTest.java | 2 + .../com/zhaogd/collection/LinkedListTest.java | 2 + .../java/com/zhaogd/collection/StackTest.java | 2 + .../com/coderising/download/DownloadUtil.java | 2 +- .../coderising/download/FileDownloader.java | 10 +- .../download/impl/ConnectionImpl.java | 14 +- .../jvm/loader/ClassFileLoader.java | 93 ++ .../jvm/test/ClassFileloaderTest.java | 80 + .../com/coderising/jvm/test/EmployeeV1.java | 30 + .../coderising/litestruts/LoginAction.java | 39 + .../src/litestruts/Configuration.java | 109 +- .../src/litestruts/ConfigurationTest.java | 40 +- .../382266293/src/litestruts/StrutsTest.java | 12 +- group12/382266293/src/litestruts/struts.xml | 4 +- .../coderising/download/DownloadThread.java | 31 +- .../coderising/download/FileDownloader.java | 66 +- .../download/impl/ConnectionImpl.java | 53 +- .../download/impl/ConnectionManagerImpl.java | 2 +- .../download/test/ConnectionTest.java | 53 + .../download/test/FileDownloaderTest.java | 59 + .../jvm/loader/ClassFileLoader.java | 43 + .../jvm/test/ClassFileloaderTest.java | 92 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../coderising/litestruts/Configuration.java | 91 ++ .../litestruts/ConfigurationTest.java | 39 + .../coderising/litestruts/LoginAction.java | 3 - .../coderising/litestruts/ReflectionUtil.java | 75 + .../litestruts/ReflectionUtilTest.java | 96 ++ .../src/com/coderising/litestruts/Struts.java | 109 +- .../array}/ArrayList.java | 15 +- .../array/ArrayUtil.java | 208 +-- .../array/ArrayUtilTest.java | 2 +- .../basic/BinaryTreeNode.java | 2 +- .../src/com/datastructure/basic/Iterator.java | 7 + .../src/com/datastructure/basic/List.java | 9 + .../basic/Queue.java | 4 +- .../basic/Stack.java | 4 +- .../datastructure/linklist/LRUPageFrame.java | 158 ++ .../linklist/LRUPageFrameTest.java | 46 + .../linklist}/LinkedList.java | 157 +- .../src/com/coderising/array/ArrayUtil.java | 96 ++ .../coderising/download/DownloadThread.java | 50 + .../coderising/download/FileDownloader.java | 126 ++ .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 73 + .../download/impl/ConnectionManagerImpl.java | 15 + .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 34 + .../com/coderising/litestruts/StrutsTest.java | 43 + .../src/com/coderising/litestruts/View.java | 23 + .../src/com/coding/basic/ArrayList.java | 32 + .../src/com/coding/basic/BinaryTreeNode.java | 32 + .../src/com/coding/basic/Iterator.java | 0 .../src/com/coding/basic}/LinkedList.java | 4 +- .../src/com/coding/basic/List.java | 0 .../src/com/coding/basic/Queue.java | 19 + .../src/com/coding/basic/Stack.java | 22 + .../jvm/loader/ClassFileLoader.java | 81 ++ .../jvm/test}/ClassFileloaderTest.java | 89 +- .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../563253496/week4_lru/src/LRUPageFrame.java | 135 ++ .../week4_lru/src/LRUPageFrameTest.java | 34 + .../vxzh/jvm/loader/ClassFileLoader.java | 79 + .../vxzh/jvm/test/ClassFileloaderTest.java | 82 ++ .../io/github/vxzh/jvm/test/EmployeeV1.java | 29 + .../src/io/github/vxzh/lru/LRUPageFrame.java | 109 ++ .../io/github/vxzh/lru/LRUPageFrameTest.java | 29 + group13/2931408816/lesson4/build.gradle | 27 + .../jvm/loader/ClassFileLoader.java | 56 + .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../java/com/coding/basic/BinaryTreeNode.java | 32 + .../main/java}/com/coding/basic/Iterator.java | 0 .../src/main/java}/com/coding/basic/List.java | 0 .../src/main/java/com/coding/basic/Queue.java | 19 + .../src/main/java/com/coding/basic/Stack.java | 24 + .../com/coding/basic/array/ArrayList.java | 35 + .../com/coding/basic/array/ArrayUtil.java | 96 ++ .../coding/basic/linklist/LRUPageFrame.java | 118 ++ .../com/coding/basic/linklist/LinkedList.java | 125 ++ .../jvm/loader/ClassFileloaderTest.java | 92 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + group13/2931408816/settings.gradle | 1 + .../413007522/dataStructure/MyArrayList.java | 239 +++ .../413007522/dataStructure/MyBinaryTree.java | 10 + .../413007522/dataStructure/MyIterator.java | 10 + .../413007522/dataStructure/MyLinkedList.java | 218 +++ group13/413007522/dataStructure/MyList.java | 10 + group13/413007522/dataStructure/MyQueue.java | 137 ++ group13/413007522/dataStructure/MyStack.java | 124 ++ .../main/java/cn/xl/c3/DownloadStartup.java | 14 + .../src/main/java/cn/xl/c3/DownloadTask.java | 411 ++++++ .../main/java/cn/xl/c3/DownloadThread.java | 113 ++ .../main/java/cn/xl/c3/FileDownloader.java | 215 +++ .../java/cn/xl/c3/FileDownloaderTest.java | 63 + .../main/java/cn/xl/c3/api/Connection.java | 31 + .../cn/xl/c3/api/ConnectionException.java | 5 + .../java/cn/xl/c3/api/ConnectionManager.java | 10 + .../java/cn/xl/c3/api/DownloadListener.java | 5 + .../java/cn/xl/c3/impl/ConnectionImpl.java | 116 ++ .../cn/xl/c3}/impl/ConnectionManagerImpl.java | 15 +- .../cn/xl/basic/linklist/LRUPageFrame.java | 127 ++ .../xl/basic/linklist/LRUPageFrameTest.java | 31 + .../cn/xl/jvm/loader/ClassFileLoader.java | 69 + .../java/cn/xl/jvm/loader/EmployeeV1.java | 28 + .../java/jvm/loader/ClassFileloaderTest.java | 93 ++ .../src/com/m0226/basic/LinkedList.java | 2 +- .../src/com/m0226/test/TestAPIDemo.java | 34 +- .../com/m0312/download/DownloadThread.java | 70 + .../com/m0312/download/FileDownloader.java | 129 ++ .../m0312/download/FileDownloaderTest.java | 62 + .../com/m0312/download/LinkedListTest.java | 137 ++ .../com/m0312/download/api/Connection.java | 27 + .../download/api/ConnectionException.java | 5 + .../m0312/download/api/ConnectionManager.java | 10 + .../m0312/download/api/DownloadListener.java | 5 + .../com/m0312/download/api/LinkedList.java | 361 +++++ .../m0312/download/impl/ConnectionImpl.java | 41 + .../download/impl/ConnectionManagerImpl.java | 28 + .../{work_1_20170225 => homework}/ReadMe.md | 0 .../src/Main.java | 0 .../homework/src/com/array/ArrayUtil.java | 96 ++ .../coderising/download/DownloadThread.java | 41 + .../coderising/download/FileDownloader.java | 73 + .../download/FileDownloader_real.java | 99 ++ .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 47 + .../download/impl/ConnectionManagerImpl.java | 44 + .../src/com/coding/basic/ArrayList.java | 0 .../src/com/coding/basic/BinaryTreeNode.java | 32 + .../src/com/coding/basic/Iterator.java | 7 + .../src/com/coding/basic/LinkedList.java | 0 .../homework}/src/com/coding/basic/List.java | 1 - .../src/com/coding/basic/Queue.java | 0 .../src/com/coding/basic/Stack.java | 0 .../test/ArrayList_Test.java | 0 .../homework/test/FileDownloaderTest.java | 107 ++ .../test/LinkedList_Test.java | 0 .../test/Queue_Test.java | 0 .../test/Stack_Test.java | 0 group14/187114392/work_1_20170225/.classpath | 6 - group14/187114392/work_1_20170225/.gitignore | 1 - group14/187114392/work_1_20170225/.idea/.name | 1 - .../work_1_20170225/.idea/compiler.xml | 22 - .../.idea/copyright/profiles_settings.xml | 3 - .../work_1_20170225/.idea/encodings.xml | 6 - .../.idea/junitgenerator-prj-settings.xml | 11 - .../187114392/work_1_20170225/.idea/misc.xml | 26 - .../work_1_20170225/.idea/modules.xml | 8 - .../work_1_20170225/.idea/uiDesigner.xml | 124 -- .../work_1_20170225/.idea/work_1_20170225.iml | 9 - .../work_1_20170225/.idea/workspace.xml | 1295 ----------------- group14/187114392/work_1_20170225/.project | 17 - .../.settings/org.eclipse.jdt.core.prefs | 11 - .../work_1_20170225/2017Learning.iml | 23 - .../coderising/download/DownloadThread.java | 40 + .../coderising/download/FileDownloader.java | 127 ++ .../download/FileDownloaderTest.java | 60 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 8 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 70 + .../download/impl/ConnectionManagerImpl.java | 15 + .../com/coderising/linkedlist/LinkedList.java | 330 +++++ .../src/org/comm/util/IntegerUtil.java | 10 + .../2017project/src/org/download/DownImg.java | 53 + .../src/org/learning/container/ArrayUtil.java | 2 +- .../src/com/coderising/array/ArrayUtil.java | 0 .../com/coderising/array/ArrayUtilTest.java | 0 .../coderising/download/DownloadThread.java | 48 + .../coderising/download/FileDownloader.java | 97 ++ .../download/FileDownloaderTest.java | 62 + .../coderising/download/api/Connection.java | 27 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 13 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 58 + .../download/impl/ConnectionManagerImpl.java | 30 + .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 0 .../com/coderising/litestruts/StrutsTest.java | 0 .../src/com/coderising/litestruts/View.java | 23 + .../src/com/coding/basic/ArrayList.java | 0 .../src/com/coding/basic/Iterator.java | 7 + .../src/com/coding/basic/LinkedList.java | 382 +++++ .../src/com/coding/basic/LinkedListbak.java} | 6 +- .../src/com/coding/basic/List.java | 9 + .../src/com/coding/basic/Queue.java | 2 +- .../src/com/coding/basic/Stack.java | 0 .../coding/basic/linklist/LRUPageFrame.java | 126 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../com/coding/basic/linklist/LinkedList.java | 384 +++++ .../src/com/coding/basic/test.java | 26 + .../src/com/testself/testss.java | 18 + .../test/com/coding/basic/LinkedListTest.java | 327 +++++ .../com/coding/basic/LinkedListbakTest.java | 138 ++ .../1502_1617273078/data-structure/test.jpg | Bin 0 -> 45215 bytes .../jvm/loader/ClassFileLoader.java | 86 ++ .../jvm/test/ClassFileloaderTest.java | 93 ++ .../com/coderising/jvm}/test/EmployeeV1.java | 10 +- .../src/com/coderising/litestruts/struts.xml | 11 - .../downland&LinkedList/LinkedList.java | 385 +++++ .../downland&LinkedList/LinkedListTest.java | 265 ++++ .../src/DownloadThread.java | 41 + .../src/FileDownloader.java | 91 ++ .../src/FileDownloaderTest.java | 53 + .../src/api/Connection.java | 23 + .../src/api/ConnectionException.java | 5 + .../src}/api/ConnectionManager.java | 2 +- .../src}/api/DownloadListener.java | 2 +- .../src/impl/ConnectionImpl.java | 44 + .../src/impl/ConnectionManagerImpl.java | 27 + .../src/impl/URLConnectionDownloader.java | 47 + .../myCollection/src/LinkedList.java | 131 +- .../src/task3/download/DownloadThread.java | 48 + .../src/task3/download/FileDownloader.java | 80 + .../task3/download/FileDownloaderTest.java | 55 + .../src/task3/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../task3/download/api/ConnectionManager.java | 10 + .../task3/download/api/DownloadListener.java | 5 + .../task3/download/impl/ConnectionImpl.java | 44 + .../download/impl/ConnectionManagerImpl.java | 23 + .../src/task3/linkedlist/MyLinkedList.java | 286 ++++ .../task3/linkedlist/MyLinkedListTest.java | 135 ++ .../src/task4/loader/ClassFileLoader.java | 49 + .../src/task4/loader/ClassFileloaderTest.java | 79 + .../src/task4/loader/EmployeeV1.java | 29 + .../src/task4/lru/LRUPageFrame.java | 122 ++ .../src/task4/lru/LRUPageFrameTest.java | 29 + group15/1510_739253131/README.md | 0 group15/1510_739253131/demo1.jpg | 0 .../com/bruce/homework0226/ArrayListV00.java | 151 +- .../bruce/homework0226/BinaryTreeNode.java | 108 ++ .../com/bruce/homework0226/IteratorV00.java | 9 + .../src/com/bruce/homework0226/JuintTest.java | 2 - .../com/bruce/homework0226/LinkedListV00.java | 31 +- .../com/bruce/homework0226/LinkedListV01.java | 139 ++ .../src/com/bruce/homework0226/StackV00.java | 10 +- .../homework0305/array/JuintArrayUtil.java | 19 +- .../demostruts/Configuration.java | 106 ++ .../demostruts/ConfigurationTest.java | 29 + .../homework0305/demostruts/LoginAction.java | 39 + .../homework0305/demostruts/ReflectUtil.java | 65 + .../demostruts/ReflectUtilTest.java | 51 + .../bruce/homework0305/demostruts/Struts.java | 53 + .../homework0305/demostruts/StrutsTest.java | 66 + .../bruce/homework0305/demostruts/View.java | 23 + .../homework0312/download/DownloadThread.java | 44 + .../homework0312/download/FileDownloader.java | 111 ++ .../download/FileDownloaderTest.java | 49 + .../homework0312/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 9 + .../download/api/ConnectionManager.java | 12 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 74 + .../download/impl/ConnectionManagerImpl.java | 18 + .../linkedlist/LinkedListV02.java | 292 ++++ .../mydownload/DownloadFileMultiThread.java | 88 ++ .../homework0312/mydownload/DownloadTest.java | 17 + .../jvm/loader/ClassFileLoader.java | 61 + .../jvm/test/ClassFileloaderTest.java | 71 + .../homework0402/jvm/test/EmployeeV1.java | 28 + .../bruce/homework0402/lru/LRUPageFrame.java | 124 ++ .../homework0402/lru/LRUPageFrameTest.java | 37 + group15/1511_714512544/.idea/encodings.xml | 1 + group15/1511_714512544/.idea/workspace.xml | 871 +++++------ .../com/coderising/array/ArrayUtil.class | Bin 3030 -> 3088 bytes .../basic/LinkedList$ListIterator.class | Bin 1427 -> 1427 bytes .../com/coding/basic/LinkedList$Node.class | Bin 541 -> 541 bytes .../com/coding/basic/LinkedList.class | Bin 3173 -> 6820 bytes ...344\272\214\345\217\211\346\240\221AVL.md" | 5 + .../com/coding/basic/LinkedListTest.class | Bin 3856 -> 6626 bytes .../src/com/coderising/array/ArrayUtil.java | 6 + .../src/com/coderising/download/Demo.java | 99 ++ .../coderising/download/DownloadThread.java | 58 + .../coderising/download/FileDownloader.java | 81 ++ .../download/FileDownloaderTest.java | 58 + .../coderising/download/api/Connection.java | 24 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 68 + .../download/impl/ConnectionManagerImpl.java | 38 + .../src/com/coding/basic/LinkedList.java | 212 +++ .../src/com/coding/basic/List.java | 3 + ...344\272\214\345\217\211\346\240\221AVL.md" | 5 + .../test/com/coding/basic/LinkedListTest.java | 145 ++ ...07\347\253\240\345\234\260\345\235\200.md" | 2 + .../jvm/loader/ClassFileLoader.java | 54 + .../jvm/test/ClassFileloaderTest.java | 89 ++ .../coderising/jvm/test/EmployeeV1.java | 28 + .../coding/basic/linklist/LRUPageFrame.java | 100 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../src/task0228/coding/basic}/ArrayList.java | 55 +- .../coding/basic/BinaryTreeNode.java | 2 +- .../src/task0228/coding/basic}/Iterator.java | 2 +- .../task0228/coding/basic}/LinkedList.java | 2 +- .../src/task0228/coding/basic/List.java | 9 + .../src/task0228}/coding/basic/Queue.java | 2 +- .../src/task0228/coding/basic}/Stack.java | 2 +- .../coding/basic}/array/ArrayUtil.java | 20 +- .../conderising/litestruts/LoginAction.java | 39 + .../conderising}/litestruts/Struts.java | 6 +- .../conderising/litestruts/StrutsTest.java | 44 + .../task0305/conderising/litestruts/View.java | 23 + .../coderising/download/DownloadThread.java | 59 + .../coderising/download/FileDownloader.java | 80 + .../download/FileDownloaderTest.java | 62 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 7 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 50 + .../download/impl/ConnectionManagerImpl.java | 33 + .../coding/basic/linkedlist/LinkedList.java | 413 ++++++ group15/1513_121469918/HomeWork01/.classpath | 6 - group15/1513_121469918/HomeWork01/.gitignore | 1 - group15/1513_121469918/HomeWork01/.project | 17 - .../org.eclipse.core.resources.prefs | 8 - .../.settings/org.eclipse.jdt.core.prefs | 11 - .../HomeWork01/src/coding/Queue.java | 35 - .../HomeWork20170305/.classpath | 9 - .../1513_121469918/HomeWork20170305/.project | 17 - .../org.eclipse.core.resources.prefs | 9 - .../.settings/org.eclipse.jdt.core.prefs | 11 - .../bin/com/coderising/litestruts/struts.xml | 11 - .../src/com/coderising/litestruts/struts.xml | 11 - .../src/com/coding/basic/ArrayList.java | 118 -- .../src/com/coding/basic/LinkedList.java | 170 --- .../src/com/coding/basic/Stack.java | 41 - group15/1515_337959725/.classpath | 2 +- group15/1515_337959725/.project | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 11 - .../coderising/download/DownloadThread.java | 27 + .../coderising/download/FileDownloader.java | 77 + .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 24 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 11 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 48 + .../download/impl/ConnectionManagerImpl.java | 31 + .../com/coding/basic/SingleLinkedList.java | 252 ++++ .../src/com/coderising/litestruts/Struts.java | 2 +- .../src/my/collection/linear/LinkedList.java | 218 +++ .../my/collection/linear/LinkedListTest.java | 157 ++ .../coding/coderising/litestruts/struts.xml | 12 - .../basic/WArrayList.java} | 27 +- .../basic/WBinaryTreeNode.java} | 4 +- .../src/task1/basic/WIterator.java | 7 + .../basic/WLinkedList.java} | 164 ++- .../1521_653895972/src/task1/basic/WList.java | 9 + .../Queue.java => task1/basic/WQueue.java} | 6 +- .../Stack.java => task1/basic/WStack.java} | 6 +- .../basic => task1/test}/BasicTest.java | 25 +- .../src/task1/test/WLinkedListTest.java | 98 ++ .../array/ArrayUtilTest.java | 2 +- .../array/SimpleArrayUtil.java | 2 +- .../litestruts/LoginAction.java | 2 +- .../litestruts/Struts.java | 2 +- .../coderising => task2}/litestruts/View.java | 2 +- .../src/task2/test/StrutsTest.java | 45 + .../src/task3/basic/WLinkedList.java | 534 +++++++ .../src/task3/download/DownloadThread.java | 38 + .../src/task3/download/FileDownloader.java | 94 ++ .../src/task3/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../task3/download/api/ConnectionManager.java | 10 + .../task3/download/api/DownloadListener.java | 5 + .../task3/download/impl/ConnectionImpl.java | 55 + .../download/impl/ConnectionManagerImpl.java | 13 + .../src/task3/test/FileDownloaderTest.java | 60 + .../src/task3/test/WLinkedListTest.java | 72 + .../1012075117/DataStructure219/.classpath | 6 - group16/1012075117/DataStructure219/.project | 17 - .../.settings/org.eclipse.jdt.core.prefs | 11 - .../coderising/download/DownloadThread.java | 49 + .../coderising/download/FileDownloader.java | 116 ++ .../download/FileDownloaderTest.java | 40 + .../coderising/download/api/Connection.java | 29 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 65 + .../download/impl/ConnectionManagerImpl.java | 38 + .../coderising/litestruts/LoginAction.java | 34 + .../src/com/coderising/litestruts/Struts.java | 182 +++ .../com/coderising/litestruts/StrutsTest.java | 39 + .../src/com/coderising/litestruts/View.java | 26 + .../com/coding/basic}/ArrayList.java | 9 +- .../src/com/coding/basic/Iterator.java | 6 + .../com/coding/basic}/LinkedList.java | 9 +- .../1012075117/src/com/coding/basic/List.java | 13 + .../com/coding/basic}/Queue.java | 9 +- .../com/coding/basic}/Stack.java | 9 +- .../src/com/coding/basic/array/ArrayUtil.java | 263 ++++ .../com/coding/basic/array/ArrayUtilTest.java | 161 ++ .../coding/basic/linklist/LRUPageFrame.java | 59 + .../basic/linklist/LRUPageFrameTest.java | 31 + .../com/coding/basic/linklist/LinkedList.java | 154 ++ group16/2562124714/.idea/misc.xml | 18 +- group16/2562124714/.idea/workspace.xml | 794 ++++++++-- group16/2562124714/src/Test/StrutsTest.java | 43 + group16/2562124714/src/Test/TestRunner.java | 2 +- .../com/coderising/action/LoginAction.java | 41 + .../src/com/coderising/array/ArrayUtil.java | 292 ++++ .../coderising/download/DownloadThread.java | 37 + .../coderising/download/FileDownloader.java | 128 ++ .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 55 + .../download/impl/ConnectionManagerImpl.java | 35 + .../src/com/coderising/litestruts/Struts.java | 128 ++ .../src/com/coderising/litestruts/View.java | 23 + .../src/com/coding/basic/ArrayList.java | 19 + .../thirdExercise/src/DownloadThread.java | 34 + .../thirdExercise/src/FileDownloader.java | 74 + .../thirdExercise/src/FileDownloaderTest.java | 57 + .../thirdExercise/src}/api/Connection.java | 4 +- .../src/api/ConnectionException.java | 5 + .../src/api/ConnectionManager.java | 10 + .../src/api/DownloadListener.java | 5 + .../thirdExercise/src/basic/Iterator.java | 11 + .../thirdExercise/src/basic/LinkedList.java | 378 +++++ .../src/basic/LinkedListTest.java | 147 ++ .../thirdExercise/src/basic/List.java | 17 + .../src/impl/ConnectionImpl.java | 64 + .../src/impl/ConnectionManagerImpl.java | 15 + group16/313001956/.classpath | 1 + .../src/com/coderising/array/ArrayUtil.java | 202 +++ .../coderising/download/DownloadThread.java | 57 + .../coderising/download/FileDownloader.java | 97 ++ .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 43 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 80 + .../download/impl/ConnectionManagerImpl.java | 35 + .../jvm/loader/ClassFileLoader.java | 56 + .../jvm/test/ClassFileloaderTest.java | 91 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../coderising/litestruts/LoginAction.java | 42 + .../src/com/coderising/litestruts/Struts.java | 108 ++ .../com/coderising/litestruts/StrutsTest.java | 43 + .../src/com/coderising/litestruts/View.java | 26 + .../src/com/coding/basic/ArrayList.java | Bin 1503 -> 1570 bytes .../src/com/coding/basic/LinkedList.java | Bin 2332 -> 7771 bytes .../src/com/coding/basic/LinkedListTest.java | 28 + .../coding/basic/linklist/LRUPageFrame.java | 135 ++ .../basic/linklist/LRUPageFrameTest.java | 35 + .../src/com/coderising/array/ArrayUtil.java | 132 +- .../src/com/coderising/array/ArrayUtil.java | 96 ++ .../coderising/download/DownloadThread.java | 20 + .../coderising/download/FileDownloader.java | 73 + .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 27 + .../download/impl/ConnectionManagerImpl.java | 15 + .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 34 + .../com/coderising/litestruts/StrutsTest.java | 43 + .../src/com/coderising/litestruts/View.java | 23 + .../src/com/coding/basic/ArrayList.java | 32 + .../src/com/coding/basic/BinaryTreeNode.java | 32 + .../src/com/coding/basic/Iterator.java | 7 + .../src/com/coding/basic/LinkedList.java | 124 ++ .../Homework3/src/com/coding/basic/List.java | 9 + .../Homework3/src/com/coding/basic/Queue.java | 19 + .../Homework3/src/com/coding/basic/Stack.java | 22 + .../src/cn/mark/work0219/MyLinkedList.java | 31 +- .../src/cn/mark/work0312/MutiDownload.java | 163 +++ group17/1158154002/src/test03/Iterator.java | 6 + group17/1158154002/src/test03/LinkedList.java | 284 ++++ .../1158154002/src/test03}/List.java | 2 +- group17/1158154002/src/test03/MyTest.java | 150 ++ .../java/com/coding/basic/LinkedList.java | 121 +- .../src/main/java/com/coding/basic/List.java | 1 + .../java/com/coding/api/ArrayListTest.java | 25 - .../java/com/coding/basic/LinkedListTest.java | 169 ++- .../1204187480/code/homework/parent/pom.xml | 9 + group17/1264835468/.gitignore | 6 +- .../ArrayUtil.java | 366 ++--- .../ArrayUtilTest.java | 200 +-- .../src/assignment0226/LoginAction.java | 42 + .../Struts.java | 198 +-- .../src/assignment0226/StrutsTest.java | 38 + .../1264835468/src/assignment0226/View.java | 26 + .../XmlParser.java | 144 +- .../jvm/loader/ClassFileLoader.java | 59 + .../jvm/test/ClassFileLoaderTest.java | 95 ++ .../assignment0326/jvm/test/EmployeeV1.java | 28 + .../src/assignment0326/lru/Clock.java | 99 ++ .../src/assignment0326/lru/LRUPageFrame.java | 128 ++ .../assignment0326/lru/LRUPageFrameTest.java | 34 + group17/1264835468/src/struts.xml | 2 +- .../jvm/loader/ClassFileLoader.java | 86 ++ .../jvm/test/ClassFileloaderTest.java | 103 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../src/com/coding/basic/LinkedList.java | 8 +- .../coding/basic/linklist/LRUPageFrame.java | 170 +++ .../basic/linklist/LRUPageFrameTest.java | 55 + .../coding/basic/linklist/LRUPageFrame.java | 126 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../com/coding/basic/linklist/LinkedList.java | 125 ++ .../jvm/loader/ClassFileLoader.java | 73 + .../jvm/test/ClassFileloaderTest.java | 92 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + group17/785396327/3.12/link/LinkedList.java | 317 ++++ .../785396327/3.12/link/LinkedListTest.java | 145 ++ .../785396327/3.26/jvm_1/ClassFileLoader.java | 50 + .../3.26/jvm_1}/ClassFileloaderTest.java | 22 +- group17/785396327/3.26/jvm_1/EmployeeV1.java | 32 + group17/785396327/3.26/lru/LRUPageFrame.java | 131 ++ .../785396327/3.26/lru/LRUPageFrameTest.java | 47 + .../jvm/loader/ClassFileLoader.java | 104 ++ .../com/coderising/jvm/test/EmployeeV1.java | 29 + .../com/coding/basic/LRU/LRUPageFrame.java | 147 ++ .../jvm/loader/ClassFileLoaderTest.java | 73 + .../coding/basic/LRU/LRUPageFrameTest.java | 29 + group17/article/20170326-20170402.md | 56 + group17/article/20170402-20170409.md | 56 + group17/article/template.md | 8 +- group17/count/homework.md | 4 + group17/count/reward.md | 16 + .../src/TestCollection/ArrayUtil.java | 259 ++++ .../1158477486/src/TestCollection/Struts.java | 119 ++ .../src/TestCollection/StrutsTest.java | 51 + .../1158477486/src/TestCollection/View.java | 43 + .../com/github/mrwengq/first/LinkedList.java | 39 +- .../github/mrwengq/first/LinkedListTest.java | 19 +- .../github/mrwengq/tid/DownloadThread.java | 43 + .../github/mrwengq/tid/FileDownloader.java | 129 ++ .../mrwengq/tid/FileDownloaderTest.java | 60 + .../github/mrwengq/tid/api/Connection.java | 23 + .../mrwengq/tid/api/ConnectionException.java | 5 + .../mrwengq/tid/api/ConnectionManager.java | 10 + .../mrwengq/tid/api/DownloadListener.java | 5 + .../mrwengq/tid/impl/ConnectionImpl.java | 72 + .../tid/impl/ConnectionManagerImpl.java | 21 + .../com/github/mrwengq/tid/list/Iterator.java | 10 + .../github/mrwengq/tid/list/LinkedList.java | 401 +++++ .../mrwengq/tid/list/LinkedListTest.java | 176 +++ .../src/com/github/mrwengq/tid/list/List.java | 16 + .../coderising/download/DownloadThread.java | 31 + .../coderising/download/FileDownloader.java | 105 ++ .../download/FileDownloaderTest.java | 62 + .../coderising/download/api/Connection.java | 24 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 86 ++ .../download/impl/ConnectionManagerImpl.java | 25 + .../src/com/coding/basic/LinkedList.java | 30 +- .../coderising/download/DownloadThread.java | 35 + .../coderising/download/FileDownloader.java | 81 ++ .../download/FileDownloaderTest.java | 53 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 51 + .../download/impl/ConnectionManagerImpl.java | 14 + .../week01/src/basic/ArrayList.java | 6 +- .../week01/src/basic/LinkedList.java | 101 +- .../src/thirdwork/DownloadThread.java | 5 + .../src/thirdwork/FileDownloader.java | 5 + .../src/thirdwork/api/Connection.java | 5 + .../thirdwork/api/ConnectionException.java | 5 + .../src/thirdwork/api/ConnectionManager.java | 5 + .../src/thirdwork/api/DownloadListener.java | 5 + .../src/thirdwork/impl/ConnectionImpl.java | 5 + .../thirdwork/impl/ConnectionManagerImpl.java | 5 + group22/2622819383/Task1/LinkedList.java | 138 +- group22/2622819383/Task2/ArrayUtil.java | 272 ++++ .../Task2/litestruts/LoginAction.java | 41 + .../2622819383/Task2/litestruts/Struts.java | 167 +++ .../Task2/litestruts/StrutsTest.java | 43 + .../2622819383/Task2}/litestruts/View.java | 2 +- group22/2622819383/Task3/LinkedList.java | 181 +++ .../2622819383/Task3/download/Connection.java | 53 + .../Task3/download/DownloadThread.java | 34 + .../Task3/download/FileDownloader.java | 66 + .../src/com/coding/basic/LinkedList.java | 48 +- ...64\347\232\204\345\205\263\347\263\273.md" | 0 .../src/com/coding/basic/ArrayList.java | 24 +- .../src/com/coding/basic/BinaryTreeNode.java | 22 +- .../src/com/coding/basic/LinkedList.java | 90 +- .../src/com/coderising/array/ArrayUtil.java | 235 +++ .../com/coderising/array/ArrayUtilTest.java | 58 + .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 95 ++ .../src/com/coderising/litestruts/View.java | 23 + .../com/coderising/litestruts/StrutsTest.java | 40 + .../src/com/coding/basic/LinkedList.java | 143 ++ .../java/me/lzb/common/utils/ByteUtils.java | 26 + .../java/me/lzb/common}/utils/FileUtils.java | 12 +- .../me/lzb/common}/utils/StringUtils.java | 3 +- .../learning2017/learning-basic/pom.xml | 5 + .../{datastructure => basic}/ArrayList.java | 2 +- .../{datastructure => basic}/ArrayUtil.java | 2 +- .../BinaryTreeNode.java | 2 +- .../src/main/java/me/lzb/basic/InfixExpr.java | 161 ++ .../{datastructure => basic}/Iterator.java | 2 +- .../{algorithm => basic}/LRUPageFrame.java | 2 +- .../{datastructure => basic}/LinkedList.java | 2 +- .../me/lzb/{datastructure => basic}/List.java | 2 +- .../lzb/{datastructure => basic}/Queue.java | 2 +- .../lzb/{datastructure => basic}/Stack.java | 2 +- .../src/main/java/me/lzb/basic/StackUtil.java | 155 ++ .../ArrayListTest.java | 6 +- .../test/java/me/lzb/basic/InfixExprTest.java | 48 + .../LRUPageFrameTest.java | 3 +- .../LinkedListTest.java | 6 +- .../test/java/me/lzb/basic/StackUtilTest.java | 78 + .../java/me/lzb/jvm/attr/AttributeInfo.java | 22 + .../main/java/me/lzb/jvm/attr/CodeAttr.java | 52 + .../java/me/lzb/jvm/attr/LineNumberItem.java | 31 + .../java/me/lzb/jvm/attr/LineNumberTable.java | 23 + .../me/lzb/jvm/attr/LocalVariableItem.java | 62 + .../me/lzb/jvm/attr/LocalVariableTable.java | 20 + .../java/me/lzb/jvm/attr/StackMapTable.java | 15 + .../main/java/me/lzb/jvm/clz/AccessFlag.java | 29 + .../main/java/me/lzb/jvm/clz/ClassFile.java | 131 ++ .../main/java/me/lzb/jvm/clz/ClassIndex.java | 25 + .../java/me/lzb/jvm/constant/ClassInfo.java | 33 + .../me/lzb/jvm/constant/ConstantInfo.java | 44 + .../me/lzb/jvm/constant/ConstantPool.java | 32 + .../me/lzb/jvm/constant/FieldRefInfo.java | 35 + .../me/lzb/jvm/constant/MethodRefInfo.java | 36 + .../me/lzb/jvm/constant/NameAndTypeInfo.java | 36 + .../me/lzb/jvm/constant/NullConstantInfo.java | 12 + .../java/me/lzb/jvm/constant/StringInfo.java | 26 + .../java/me/lzb/jvm/constant/UTF8Info.java | 38 + .../src/main/java/me/lzb/jvm/field/Field.java | 30 + .../me/lzb/jvm/loader/ClassFileLoader.java | 56 + .../me/lzb/jvm/loader/ClassFileParser.java | 331 +++++ .../main/java/me/lzb/jvm/method/Method.java | 65 + .../java/me/lzb/loader/ClassFileLoader.java | 57 - .../java/me/lzb/jvm/ClassFileloaderTest.java | 269 ++++ .../me/lzb/{loader => jvm}/EmployeeV1.java | 2 +- .../main/java/me/lzb/other/graph/Graph.java | 366 +++++ .../me/lzb/other/lock/ReentrantTest1.java | 27 + .../me/lzb/other/lock/ReentrantTest2.java | 35 + .../lzb/other/proxy/MyInvocationHandler.java | 52 + .../java/me/lzb/other/proxy/UserService.java | 11 + .../me/lzb/other/proxy/UserServiceImpl.java | 11 + .../java/me/lzb/other/proxy/ProxyTest.java | 25 + group24/1148285693/learning2017/pom.xml | 8 +- .../coding2017/basic/{ => stack}/Stack.java | 12 +- .../coding2017/basic/stack/StackUtil.java | 133 ++ .../basic/stack/expr/InfixExpr.java | 83 ++ .../basic/stack/expr/InfixExprTest.java | 50 + .../coding2017/basic/test/StackTest.java | 2 +- .../coding2017/basic/test/StackUtilTest.java | 73 + .../minijvm/attr/AttributeInfo.java | 21 + .../coding2017/minijvm/attr/CodeAttr.java | 85 ++ .../minijvm/attr/LineNumberTable.java | 53 + .../minijvm/attr/LocalVariableItem.java | 39 + .../minijvm/attr/LocalVariableTable.java | 41 + .../minijvm/attr/StackMapTable.java | 29 + .../coding2017/minijvm/clz/AccessFlag.java | 37 + .../coding2017/minijvm/clz/ClassFile.java | 92 ++ .../coding2017/minijvm/clz/ClassIndex.java | 21 + .../minijvm/constant/ClassInfo.java | 26 + .../minijvm/constant/ConstantInfo.java | 29 + .../minijvm/constant/ConstantPool.java | 29 + .../minijvm/constant/FieldRefInfo.java | 54 + .../minijvm/constant/MethodRefInfo.java | 55 + .../minijvm/constant/NameAndTypeInfo.java | 45 + .../minijvm/constant/NullConstantInfo.java | 13 + .../minijvm/constant/StringInfo.java | 26 + .../coding2017/minijvm/constant/UTF8Info.java | 32 + .../coding2017/minijvm/field/Field.java | 41 + .../minijvm/loader/ByteCodeIterator.java | 31 + .../minijvm/loader/ClassFileLoader.java | 141 +- .../minijvm/loader/ClassFileLoader1.java | 125 ++ .../minijvm/loader/ClassFileParser.java | 190 +++ .../coding2017/minijvm/method/Method.java | 70 + .../minijvm/test/ClassFileloaderTest.java | 224 ++- .../ipk2015/coding2017/minijvm/util/Util.java | 26 + .../jvm/loader/ClassFileLoader.java | 101 ++ .../jvm/test/ClassFileloaderTest.java | 86 ++ .../com/coderising/jvm/test/EmployeeV1.java | 29 + .../src/com/coderising/lru/LRUPageFrame.java | 163 +++ .../coderising/lru/test/LRUPageFrameTest.java | 34 + .../johnChnia/coding2017/basic/ArrayList.java | 19 +- .../basic/linklist/LRUPageFrame.java | 128 ++ .../basic/linklist/LRUPageFrameTest.java | 30 + .../basic/{ => linklist}/LinkedList.java | 6 +- .../coding2017/basic/{ => stack}/Stack.java | 4 +- .../coding2017/basic/stack/StackUtil.java | 122 ++ .../coding2017/basic/ArrayListTest.java | 1 - .../coding2017/basic/LinkedListTest.java | 2 +- .../johnChnia/coding2017/basic/StackTest.java | 1 + .../coding2017/basic/stack/StackUtilTest.java | 66 + .../week01/data_structure/LinkedList.java | 54 +- .../week01/data_structure/LinkedListTest.java | 29 +- .../main/week03/download/DownloadThread.java | 7 +- .../main/week03/download/FileDownloader.java | 2 +- .../week03/download/impl/ConnectionImpl.java | 11 +- .../download/impl/ConnectionManagerImpl.java | 1 + .../src/main/week03/download/test.jpg | Bin 234626 -> 234626 bytes .../src/com/donaldy/basic/ArrayList.java | 2 +- .../src/com/donaldy/basic/Stack.java | 8 +- .../src/com/donaldy/basic/StackUtil.java | 118 ++ .../src/com/donaldy/basic/expr/InfixExpr.java | 140 ++ .../com/donaldy/basic/expr/InfixExprTest.java | 48 + .../com/donaldy/jvm/attr/AttributeInfo.java | 19 + .../src/com/donaldy/jvm/attr/CodeAttr.java | 56 + .../com/donaldy/jvm/attr/LineNumberTable.java | 57 + .../donaldy/jvm/attr/LocalVariableItem.java | 39 + .../donaldy/jvm/attr/LocalVariableTable.java | 45 + .../com/donaldy/jvm/attr/StackMapTable.java | 30 + .../src/com/donaldy/jvm/clz/AccessFlag.java | 25 + .../src/com/donaldy/jvm/clz/ClassFile.java | 92 ++ .../src/com/donaldy/jvm/clz/ClassIndex.java | 19 + .../com/donaldy/jvm/constant/ClassInfo.java | 24 + .../donaldy/jvm/constant/ConstantInfo.java | 29 + .../donaldy/jvm/constant/ConstantPool.java | 29 + .../donaldy/jvm/constant/FieldRefInfo.java | 54 + .../donaldy/jvm/constant/MethodRefInfo.java | 55 + .../donaldy/jvm/constant/NameAndTypeInfo.java | 45 + .../jvm/constant/NullConstantInfo.java | 13 + .../com/donaldy/jvm/constant/StringInfo.java | 26 + .../com/donaldy/jvm/constant/UTF8Info.java | 32 + .../src/com/donaldy/jvm/field/Field.java | 46 + .../donaldy/jvm/loader/ByteCodeIterator.java | 104 ++ .../donaldy/jvm/loader/ClassFileLoader.java | 82 +- .../donaldy/jvm/loader/ClassFileParser.java | 166 +++ .../src/com/donaldy/jvm/method/Method.java | 89 ++ .../donaldy/jvm/test/ClassFileloaderTest.java | 205 ++- .../src/com/donaldy/jvm/util/Util.java | 24 + .../src/com/donaldy/test/StackUtilTest.java | 70 + .../com/coderising/jvm/clz/AccessFlag.java | 25 + .../src/com/coderising/jvm/clz/ClassFile.java | 76 + .../com/coderising/jvm/clz/ClassIndex.java | 19 + .../coderising/jvm/constant/ClassInfo.java | 24 + .../coderising/jvm/constant/ConstantInfo.java | 29 + .../coderising/jvm/constant/ConstantPool.java | 36 + .../coderising/jvm/constant/FieldRefInfo.java | 54 + .../jvm/constant/MethodRefInfo.java | 55 + .../jvm/constant/NameAndTypeInfo.java | 45 + .../jvm/constant/NullConstantInfo.java | 13 + .../coderising/jvm/constant/StringInfo.java | 26 + .../com/coderising/jvm/constant/UTF8Info.java | 32 + .../jvm/loader/ByteCodeIterator.java | 52 + .../jvm/loader/ClassFileLoader.java | 53 +- .../jvm/loader/ClassFileParser.java | 103 ++ .../src/com/coderising/jvm/util/Util.java | 40 + .../src/main/java/com/coding/weak1/Stack.java | 14 + .../com/coding/week5/stack/StackUtil.java | 103 ++ .../mini_jvm/test/ClassFileloaderTest.java | 123 +- .../com/coding/week5/stack/StackUtilTest.java | 56 + .../wdn/coding2017/basic/stack/StackUtil.java | 132 ++ .../basic/stack/expr/InfixExpr.java | 90 ++ .../basic/stack/expr/InfixExprTest.java | 50 + .../wdn/coding2017/basic/StackUtilTest.java | 57 + .../coding2017/jvm/attr/AttributeInfo.java | 20 + .../wdn/coding2017/jvm/attr/CodeAttr.java | 58 + .../coding2017/jvm/attr/LineNumberTable.java | 48 + .../jvm/attr/LocalVariableTable.java | 80 + .../jvm/attr/LocalVariableTypeTable.java | 7 + .../coding2017/jvm/attr/StackMapTable.java | 29 + .../wdn/coding2017/jvm/clz/AccessFlag.java | 37 + .../wdn/coding2017/jvm/clz/ClassFile.java | 80 + .../wdn/coding2017/jvm/clz/ClassIndex.java | 20 + .../github/wdn/coding2017/jvm/clz/Field.java | 74 + .../github/wdn/coding2017/jvm/clz/Method.java | 99 ++ .../coding2017/jvm/constant/ClassInfo.java | 35 + .../coding2017/jvm/constant/ConstantInfo.java | 30 + .../coding2017/jvm/constant/ConstantPool.java | 32 + .../coding2017/jvm/constant/FieldRefInfo.java | 39 + .../jvm/constant/MethodRefInfo.java | 37 + .../jvm/constant/NameAndTypeInfo.java | 38 + .../jvm/constant/NullConstantInfo.java | 14 + .../coding2017/jvm/constant/StringInfo.java | 30 + .../wdn/coding2017/jvm/constant/UTF8Info.java | 23 + .../jvm/loader/ByteCodeIterator.java | 42 + .../jvm/loader/ClassFileLoader.java | 11 +- .../jvm/loader/ClassFileParser.java | 105 ++ .../jvm/test/ClassFileloaderTest.java | 120 +- .../github/wdn/coding2017/jvm/util/Util.java | 24 + .../zhouliang/week2/litestruts/struts.xml | 11 - .../src/{week1 => basic}/ArrayList.java | 2 +- .../src/{week1 => basic}/ArrayListTest.java | 2 +- .../src/{week1 => basic}/BinaryTree.java | 2 +- .../src/{week1 => basic}/BinaryTreeNode.java | 2 +- .../src/{week1 => basic}/Iterator.java | 2 +- .../{week4 => basic}/LRU/LRUPageFrame.java | 2 +- .../LRU/LRUPageFrameTest.java | 2 +- .../{week4 => basic}/LRU/MyLRUPageFrame.java | 2 +- .../src/{week1 => basic}/LinkedList.java | 4 +- .../src/{week1 => basic}/LinkedListTest.java | 2 +- .../798277403/src/{week1 => basic}/List.java | 2 +- .../798277403/src/{week1 => basic}/Queue.java | 2 +- .../src/{week1 => basic}/QueueTest.java | 2 +- .../798277403/src/{week1 => basic}/Stack.java | 2 +- .../src/{week1 => basic}/StackTest.java | 2 +- .../src/{week2 => basic}/array/ArrayUtil.java | 2 +- .../{week2 => basic}/array/ArrayUtilTest.java | 2 +- .../linkedlist/LinkedList.java | 2 +- .../linkedlist/LinkedListTest.java | 4 +- .../src/{week3 => basic}/linkedlist/List.java | 2 +- .../798277403/src/basic/stack/StackUtil.java | 116 ++ .../src/basic/stack/StackUtilTest.java | 77 + .../{week3 => download}/DownloadThread.java | 6 +- .../{week3 => download}/FileDownloader.java | 8 +- .../src/download/api/Connection.java | 23 + .../api/ConnectionException.java | 2 +- .../src/download/api/ConnectionManager.java | 10 + .../src/download/api/DownloadListener.java | 5 + .../impl/ConnectionImpl.java | 8 +- .../download/impl/ConnectionManagerImpl.java | 2 + .../test/ConnectionTest.java | 9 +- .../test/FileDownloaderTest.java | 11 +- .../{week2 => }/litestruts/LoginAction.java | 2 +- .../src/{week2 => }/litestruts/Struts.java | 4 +- .../798277403/src/litestruts/StrutsTest.java | 40 + group24/798277403/src/litestruts/View.java | 23 + .../src/mini_jvm/clz/AccessFlag.java | 25 + .../798277403/src/mini_jvm/clz/ClassFile.java | 65 + .../src/mini_jvm/clz/ClassIndex.java | 19 + .../src/mini_jvm/constant/ClassInfo.java | 24 + .../src/mini_jvm/constant/ConstantInfo.java | 29 + .../src/mini_jvm/constant/ConstantPool.java | 27 + .../src/mini_jvm/constant/FieldRefInfo.java | 54 + .../src/mini_jvm/constant/MethodRefInfo.java | 55 + .../mini_jvm/constant/NameAndTypeInfo.java | 45 + .../mini_jvm/constant/NullConstantInfo.java | 13 + .../src/mini_jvm/constant/StringInfo.java | 26 + .../src/mini_jvm/constant/UTF8Info.java | 32 + .../src/mini_jvm/loader/ByteCodeIterator.java | 55 + .../src/mini_jvm/loader/ClassFileLoader.java | 94 ++ .../src/mini_jvm/loader/ClassFileParser.java | 130 ++ .../mini_jvm/test/ClassFileloaderTest.java | 189 +++ .../src/mini_jvm/test/EmployeeV1.java | 28 + group24/798277403/src/mini_jvm/util/Util.java | 22 + .../798277403/src/week2/litestruts/struts.xml | 11 - .../src/week4/loader/ClassFileLoader.java | 67 - .../src/com/coderising/array/ArrayUtil.java | 348 +++++ .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 137 ++ .../com/coderising/litestruts/StrutsTest.java | 43 + .../src/com/coderising/litestruts/View.java | 23 + .../src/com/coding/basic/ArrayList.java | 134 ++ .../src/com/coding/basic/BinaryTree.java | 35 + .../src/com/coding/basic/BinaryTreeNode.java | 109 ++ .../src/com/coding/basic/Iterator.java | 9 + .../src/com/coding/basic/LinkedList.java | 223 +++ .../src/com/coding/basic}/List.java | 12 +- .../src/com/coding/basic/Queue.java | 27 + .../src/com/coding/basic/Stack.java | 29 + .../src/com/coding/basic/TestArrayList.java | 84 ++ group26/1515345281/.gitignore | 4 +- group26/1515345281/src/Collection/blog | 1 + .../week1/collection/test/ArrayListTest.java | 2 +- .../collection/test/BinarySearchTreeTest.java | 2 +- .../week1/collection/test/LinkedListTest.java | 2 +- .../src/week1/collection/test/QueueTest.java | 2 +- .../src/week1/collection/test/StackTest.java | 2 +- .../src/week2/arrayutil/ArrayUtil.java | 8 + .../src/week2/arrayutil/ArrayUtilTest.java | 2 +- group26/1515345281/src/week2/blog | 1 + .../src/week2/struts2/Configuration.java | 122 ++ .../week2/struts2/ConfigurationException.java | 20 + .../src/week2/struts2/LoginAction.java | 76 +- .../src/week2/struts2/ReflectionUtil.java | 88 ++ .../1515345281/src/week2/struts2/Struts.java | 81 +- .../src/week2/struts2/StrutsTest.java | 41 +- .../1515345281/src/week2/struts2/View.java | 1 + .../1515345281/src/week2/struts2/struts.xml | 5 +- .../week2/struts2/test/ConfigurationTest.java | 40 + .../week2/struts2/test/ReflectionTest.java | 110 ++ group26/1515345281/src/week3/blog | 1 + .../src/week3/download/DownloadThread.java | 57 + .../src/week3/download/FileDownloader.java | 106 ++ .../src/week3}/download/api/Connection.java | 18 +- .../download/api/ConnectionException.java | 8 + .../download/api/ConnectionManager.java | 4 +- .../week3/download/api/DownloadListener.java | 6 + .../download/api/impl/ConnectionImpl.java | 81 ++ .../api/impl/ConnectionManagerImpl.java | 17 + .../week3/download/test/ConnectionTest.java | 52 + .../download/test/FileDownloaderTest.java | 45 + .../1515345281/src/week3/list/Iterator.java | 5 + .../1515345281/src/week3/list/LinkedList.java | 363 +++++ .../src/week3/list/LinkedListTest.java | 201 +++ group26/1515345281/src/week3/list/List.java | 14 + .../1515345281/src/week3/list/ListUtils.java | 9 + .../origin/jvm/loader/ClassFileLoader.java | 72 + .../week4/origin/jvm/loader/LRUPageFrame.java | 105 ++ .../src/week4/origin/jvm/loader/blog | 1 + .../jvm/loader/test/ClassFileLoaderTest.java | 55 + .../origin/jvm/loader/test/EmployeeV1.java | 28 + .../jvm/loader/test/LRUPageFrameTest.java | 32 + .../third homework/LinkedList/LinkedList.java | 518 +++++++ .../LinkedList/LinkedListTest.java | 192 +++ .../third homework/TTD/ConfigurationTest.java | 41 + .../third homework/TTD/Configureation.java | 99 ++ .../third homework/TTD/LoginAction.java | 42 + .../third homework/TTD/ReflectionUtil.java | 76 + .../TTD/ReflectionUtilTest.java | 108 ++ .../1778842360/third homework/TTD/Struts.java | 56 + .../1778842360/third homework/TTD/View.java | 27 + .../com/coding/download/DownloadThread.java | 65 + .../com/coding/download/FileDownloader.java | 145 ++ .../coding/download/FileDownloaderTest.java | 66 + .../com/coding/download/api/Connection.java | 28 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../coding/download/api/DownloadListener.java | 6 + .../coding/download/impl/ConnectionImpl.java | 70 + .../download/impl/ConnectionManagerImpl.java | 42 + .../week1/collection/MyArrayList.java | 65 + .../week1/collection/MyLinkedList.java | 115 ++ .../2441547139/week1/collection/MyQueue.java | 29 + .../2441547139/week1/collection/MyStack.java | 29 + .../week2/arrayutil/ArrayUtils.java | 172 +++ .../2441547139/week2/struts/LoginAction.java | 39 + .../week2/struts/LoginOutAction.java | 5 + group26/2441547139/week2/struts/Struts.java | 74 + group26/2441547139/week2/struts/View.java | 23 + .../week3/linkedlist/MyLinkedLists.java | 272 ++++ .../week3/thread/DownloadThread.java | 67 + .../2441547139/week3/thread/FileDownload.java | 53 + .../week3/thread/ThreadDownload.java | 35 + ...1\351\201\223\347\254\224\350\256\260.txt" | 3 + ...05\345\206\265\347\273\237\350\256\241.md" | 2 +- .../723161901/jvm/loader/ClassFileLoader.java | 63 + .../jvm/test/ClassFileloaderTest.java | 94 ++ group26/723161901/jvm/test/EmployeeV1.java | 28 + .../com/download/download/DownloadThread.java | 39 + .../com/download/download/FileDownloader.java | 116 ++ .../download/download/FileDownloaderTest.java | 59 + .../com/download/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 69 + .../download/impl/ConnectionManagerImpl.java | 15 + .../src/com/litestruts/LoginAction.java | 39 + .../723161901/src/com/litestruts/Struts.java | 91 ++ .../src/com/litestruts/StrutsTest.java | 41 + .../src/com/litestruts/StrutsXmlReader.java | 59 + .../723161901/src/com/litestruts/View.java | 23 + .../src/com/litestruts/strutsBean/Action.java | 46 + .../source/download/DownloadThread.java | 40 + .../source/download/FileDownloader.java | 101 ++ .../source/download/api/Connection.java | 16 + .../download/api/ConnectionException.java | 10 + .../download/api/ConnectionManager.java | 10 + .../source/download/api/DownloadListener.java | 10 + .../source/download/impl/ConnectionImpl.java | 43 + .../download/impl/ConnectionManagerImpl.java | 27 + .../source/linkedlist/SinglyLinkedList.java | 357 +++++ .../src/week03/test/TestDownload.java | 57 + .../src/week03/test/TestSinglyLinkedList.java | 156 ++ .../src/week04/source/LRUPageFrame.java | 159 ++ .../src/week04/test/TestLRUPageFrame.java | 32 + .../homework/second/array/ArrayUtil.java | 56 +- .../homework/second/array/ArrayUtilTest.java | 90 ++ .../homework/third/basic/LRUPageFameTest.java | 32 + .../homework/third/basic/LRUPageFrame.java | 63 + .../homework/third/basic/LinkedList.java | 204 +++ .../third/download/DownloadThread.java | 51 + .../third/download/FileDownloader.java | 86 ++ .../third/download/FileDownloaderTest.java | 58 + .../third/download/api/Connection.java | 28 + .../download/api/ConnectionException.java | 12 + .../third/download/api/ConnectionManager.java | 16 + .../third/download/api/DownloadListener.java | 5 + .../third/download/impl/ConnectionImpl.java | 97 ++ .../download/impl/ConnectionManagerImpl.java | 54 + .../third/download/utils/HttpUtil.java | 24 + .../coderising/download/DownloadThread.java | 49 + .../coderising/download/FileDownloader.java | 142 ++ .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 83 ++ .../download/impl/ConnectionManagerImpl.java | 14 + .../download/test/ConnectionTest.java | 57 + .../download/test/FileDownloaderTest.java | 66 + .../src/com/coding/basic/LinkedList.java | 283 ++++ .../jvm/loader/ClassFileLoader.java | 180 +++ .../jvm/test/ClassFileloaderTest.java | 100 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../coding/basic/linklist/LRUPageFrame.java | 152 ++ .../basic/linklist/LRUPageFrameTest.java | 31 + .../src/com/coding/ArrayListTest.java | 2 +- .../src/com/coding/LinkedList.java | 153 +- .../src/com/coding/LinkedListTest.java | 117 +- .../src/com/coderising/litestruts/Struts.java | 64 +- .../coderising/download/DownloadThread.java | 79 + .../coderising/download/FileDownloader.java | 83 ++ .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 30 + .../download/api/ConnectionException.java | 11 + .../download/api/ConnectionManager.java | 21 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 94 ++ .../download/impl/ConnectionManagerImpl.java | 61 + ...\344\270\232\345\234\250task1\351\207\214" | 1 + .../coderising/download/DownloadThread.java | 61 + .../coderising/download/FileDownloader.java | 70 + .../download/FileDownloaderTest.java | 55 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 71 + .../download/impl/ConnectionManagerImpl.java | 15 + .../jvm/loader/ClassFileLoader.java | 77 + .../jvm/test/ClassFileloaderTest.java | 76 + .../com/coderising/jvm/test/EmployeeV1.java | 30 + .../383117348/src/com/coding/basic/Queue.java | 2 + .../coding/basic/linklist/LRUPageFrame.java | 139 ++ .../basic/linklist/LRUPageFrameTest.java | 30 + .../basic/{ => linklist}/LinkedList.java | 903 +++++++----- group27/513274874/data-structure/down.jpg | Bin 0 -> 14104 bytes .../coderising/download/DownloadThread.java | 30 + .../coderising/download/FileDownloader.java | 73 + .../download/FileDownloaderTest.java | 59 + .../coderising/download/api/Connection.java | 23 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../coderising/download/demo/DownThread.java | 72 + .../coderising/download/demo/MutilDown.java | 72 + .../download/impl/ConnectionImpl.java | 100 ++ .../download/impl/ConnectionManagerImpl.java | 29 + .../coderising/litestruts/LoginAction.java | 39 + .../src/com/coderising/litestruts/Struts.java | 254 ++++ .../com/coderising/litestruts/StrutsTest.java | 53 + .../src/com/coderising/litestruts/View.java | 23 + .../src/com/coding/basic/ArrayList.java | 124 ++ .../src/com/coding/basic/BinaryTreeNode.java | 32 + .../src/com/coding/basic/Iterator.java | 7 + .../src/com/coding/basic/List.java | 9 + .../src/com/coding/basic/Queue.java | 50 + .../src/com/coding/basic/Stack.java | 65 + .../src/com/coding/basic/array/ArrayUtil.java | 262 ++++ .../com/coding/basic/array/ArrayUtilTest.java | 110 ++ .../coding/basic/linklist/LRUPageFrame.java | 158 ++ .../basic/linklist/LRUPageFrameTest.java | 52 + .../com/coding/basic/linklist/LinkedList.java | 268 ++++ .../test/com/coding/basic/ArrayListTest.java | 151 ++ group27/513274874/homework/.project | 2 +- .../src/com/coding/basic/LinkedList.java | 77 + .../coderising/download/DownloadThread.java | 26 +- .../coderising/download/FileDownloader.java | 78 +- .../download/FileDownloaderTest.java | 10 +- .../coderising/download/api/Connection.java | 2 +- .../download/api/ConnectionException.java | 2 +- .../download/api/ConnectionManager.java | 2 +- .../download/api/DownloadListener.java | 2 +- .../download/impl/ConnectionImpl.java | 115 +- .../download/impl/ConnectionManagerImpl.java | 30 +- .../jvm/loader/ClassFileLoader.java | 57 + .../jvm/test/ClassFileloaderTest.java | 91 ++ .../com/coderising/jvm/test/EmployeeV1.java | 28 + .../coderising/download/DownloadThread.java | 47 + .../coderising/download/FileDownloader.java | 91 ++ .../download/FileDownloaderTest.java | 59 + .../src/com/coderising/download/Test.java | 172 +++ .../coderising/download/api/Connection.java | 25 + .../download/api/ConnectionException.java | 5 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 44 + .../download/impl/ConnectionManagerImpl.java | 47 + .../src/com/coding/basic/LinkedList.java | 393 +++-- .../coding/basic/linklist/LRUPageFrame.java | 118 +- .../basic/linklist/LRUPageFrameTest.java | 3 + .../src/com/coding/basic/stack/Stack.java | 24 + .../src/com/coding/basic/stack/StackUtil.java | 136 ++ .../com/coding/basic/stack/StackUtilTest.java | 78 + .../coding/basic/stack/expr/InfixExpr.java | 18 + .../basic/stack/expr/InfixExprTest.java | 48 + .../coderising/jvm/attr/AttributeInfo.java | 19 + .../src/com/coderising/jvm/attr/CodeAttr.java | 56 + .../coderising/jvm/attr/LineNumberTable.java | 42 + .../jvm/attr/LocalVariableItem.java | 39 + .../jvm/attr/LocalVariableTable.java | 28 + .../coderising/jvm/attr/StackMapTable.java | 30 + .../com/coderising/jvm/clz/AccessFlag.java | 25 + .../src/com/coderising/jvm/clz/ClassFile.java | 92 ++ .../com/coderising/jvm/clz/ClassIndex.java | 19 + .../coderising/jvm/constant/ClassInfo.java | 24 + .../coderising/jvm/constant/ConstantInfo.java | 29 + .../coderising/jvm/constant/ConstantPool.java | 29 + .../coderising/jvm/constant/FieldRefInfo.java | 54 + .../jvm/constant/MethodRefInfo.java | 55 + .../jvm/constant/NameAndTypeInfo.java | 45 + .../jvm/constant/NullConstantInfo.java | 13 + .../coderising/jvm/constant/StringInfo.java | 26 + .../com/coderising/jvm/constant/UTF8Info.java | 32 + .../src/com/coderising/jvm/field/Field.java | 33 + .../jvm/loader/ByteCodeIterator.java | 57 + .../jvm/loader/ClassFileLoader.java | 112 +- .../jvm/loader/ClassFileParser.java | 151 ++ .../src/com/coderising/jvm/method/Method.java | 57 + .../jvm/test/ClassFileloaderTest.java | 209 ++- .../src/com/coderising/jvm/util/Util.java | 24 + 2015 files changed, 105252 insertions(+), 11049 deletions(-) delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructure/ArrayList.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructure/BinaryTreeNode.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructure/LinkedList.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructure/Queue.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructure/Stack.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/AllTest.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/ArrayListTest.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/BinaryTreeNodeTest.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/LinkedListTest.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/QueueTest.java delete mode 100644 group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/StackTest.java create mode 100644 group01/1814014897/zhouhui/src/week04/jvm/loader/ClassFileLoader.java create mode 100644 group01/1814014897/zhouhui/src/week04/jvm/test/ClassFileloaderTest.java create mode 100644 group01/1814014897/zhouhui/src/week04/jvm/test/EmployeeV1.java create mode 100644 group01/1814014897/zhouhui/src/week04/lru/LRUPageFrame.java create mode 100644 group01/1814014897/zhouhui/src/week04/lru/LRUPageFrameTest.java create mode 100644 group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/loader/ClassFileLoader.java create mode 100644 group01/280646174/basic/src/main/java/com/coding2017/week4/jvm/test/EmployeeV1.java create mode 100644 group01/280646174/basic/src/main/java/com/coding2017/week4/lru/LRUPageFrame.java create mode 100644 group01/280646174/basic/src/test/java/com/coding2017/week4/jvm/loader/ClassFileLoaderTest.java create mode 100644 group01/280646174/basic/src/test/java/com/coding2017/week4/lru/LRUPageFrameTest.java create mode 100644 group01/378213871/src/com/coderising/week03/basic/LinkedList.java create mode 100644 group01/378213871/src/com/coderising/week03/basic/LinkedListEx.java create mode 100644 group01/378213871/src/com/coderising/week03/basic/LinkedListTest.java create mode 100644 group01/378213871/src/com/coderising/week03/download/DownloadThread.java create mode 100644 group01/378213871/src/com/coderising/week03/download/FileDownloader.java create mode 100644 group01/378213871/src/com/coderising/week03/download/FileDownloaderTest.java create mode 100644 group01/378213871/src/com/coderising/week03/download/api/Connection.java create mode 100644 group01/378213871/src/com/coderising/week03/download/api/ConnectionException.java create mode 100644 group01/378213871/src/com/coderising/week03/download/api/ConnectionManager.java rename {group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => group01/378213871/src/com/coderising/week03/download}/api/DownloadListener.java (60%) create mode 100644 group01/378213871/src/com/coderising/week03/download/impl/ConnectionImpl.java create mode 100644 group01/378213871/src/com/coderising/week03/download/impl/ConnectionManagerImpl.java create mode 100644 group01/378213871/src/com/coderising/week03/download/test/ConnectionTest.java create mode 100644 group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java create mode 100644 group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java create mode 100644 group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java delete mode 100644 group01/895457260/code/src/download/api/DownloadListener.java delete mode 100644 group01/895457260/code/src/download/impl/ConnectionImpl.java delete mode 100644 group01/895457260/code/src/litestruts/struts.xml rename group01/895457260/code/src/{ => main/java}/algorithm/ArrayUtil.java (100%) create mode 100644 group01/895457260/code/src/main/java/algorithm/lru/LRUPageFrame.java rename group01/895457260/code/src/{ => main/java}/datastructure/basic/ArrayList.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/BinarySortedTree.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/BinaryTreeNode.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/Iterator.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/LinkedList.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/List.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/Queue.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/basic/Stack.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/exception/EmptyListException.java (100%) rename group01/895457260/code/src/{ => main/java}/datastructure/exception/EmptyQueueException.java (100%) rename group01/895457260/code/src/{ => main/java}/download/Config.java (59%) rename group01/895457260/code/src/{ => main/java}/download/DownloadThread.java (59%) rename group01/895457260/code/src/{ => main/java}/download/FileDownloader.java (69%) create mode 100644 group01/895457260/code/src/main/java/download/api/Connection.java rename group01/895457260/code/src/{ => main/java}/download/api/ConnectionException.java (100%) create mode 100644 group01/895457260/code/src/main/java/download/api/ConnectionManager.java create mode 100644 group01/895457260/code/src/main/java/download/api/DownloadCallback.java rename group01/895457260/code/src/{ => main/java}/download/api/DownloadException.java (100%) create mode 100644 group01/895457260/code/src/main/java/download/api/OnCompleteListener.java create mode 100644 group01/895457260/code/src/main/java/download/api/OnFailListener.java create mode 100644 group01/895457260/code/src/main/java/download/impl/BaseConnection.java create mode 100644 group01/895457260/code/src/main/java/download/impl/ConnectionManagerImpl.java create mode 100644 group01/895457260/code/src/main/java/download/impl/DefaultConnection.java create mode 100644 group01/895457260/code/src/main/java/download/impl/HttpConnection.java create mode 100644 group01/895457260/code/src/main/java/download/impl/HttpsConnection.java create mode 100644 group01/895457260/code/src/main/java/jvm/ClassFileLoader.java create mode 100644 group01/895457260/code/src/main/java/jvm/LiteJvm.java create mode 100644 group01/895457260/code/src/main/java/jvm/exception/ClassDuplicateException.java create mode 100644 group01/895457260/code/src/main/java/jvm/exception/ClassNotExistsException.java create mode 100644 group01/895457260/code/src/main/java/jvm/exception/MagicNumberException.java create mode 100644 group01/895457260/code/src/main/java/jvm/exception/ReadClassException.java create mode 100644 group01/895457260/code/src/main/java/jvm/util/ArrayUtils.java rename group01/895457260/code/src/{ => main/java}/litestruts/Struts.java (100%) rename group01/895457260/code/src/{ => main/java}/litestruts/View.java (100%) rename group01/895457260/code/src/{ => main/java}/litestruts/action/LoginAction.java (100%) rename group01/895457260/code/src/{ => main/java}/litestruts/exception/XmlElementNotFoundException.java (100%) rename group01/895457260/code/src/{algorithm/test => test/java/algorithm}/ArrayUtilTest.java (99%) create mode 100644 group01/895457260/code/src/test/java/algorithm/lru/LRUPageFrameTest.java rename group01/895457260/code/src/{datastructure/test => test/java/datastructure}/ArrayListTest.java (99%) rename group01/895457260/code/src/{datastructure/test => test/java/datastructure}/BinarySortedTreeTest.java (98%) rename group01/895457260/code/src/{datastructure/test => test/java/datastructure}/LinkedListTest.java (99%) rename group01/895457260/code/src/{datastructure/test => test/java/datastructure}/QueueTest.java (99%) rename group01/895457260/code/src/{datastructure/test => test/java/datastructure}/StackTest.java (98%) rename group01/895457260/code/src/{datastructure/test => test/java/datastructure}/TestSuite.java (91%) create mode 100644 group01/895457260/code/src/test/java/download/FileDownloaderTest.java create mode 100644 group01/895457260/code/src/test/java/jvm/ClassFileLoaderTest.java create mode 100644 group01/895457260/code/src/test/java/jvm/EmployeeV1.java create mode 100644 group01/895457260/code/src/test/java/jvm/LiteJvmTest.java rename group01/895457260/code/src/{litestruts/test => test/java/litestruts}/StrutsTest.java (97%) create mode 100644 group01/954958168/class01/BasicDataStructure/src/main/java/com/aaront/exercise/basic/LRUPageFrame.java create mode 100644 group01/954958168/class01/BasicDataStructure/src/test/java/com/aaront/execrise/basic/LRUPageFrameTest.java delete mode 100644 group01/954958168/class03/MultiThreadDownload/src/main/resources/test.jpg create mode 100644 group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/ClassFileLoader.java create mode 100644 group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/loader/EmployeeV1.java create mode 100644 group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/FileUtils.java create mode 100644 group01/954958168/class04/mini-jvm/src/main/java/com/aaront/exercise/jvm/utils/string/StringUtils.java create mode 100644 group01/954958168/class04/mini-jvm/src/test/java/com/aaront/exercise/jvm/loader/ClassFileLoaderTest.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/DownloadThread.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/FileDownloader.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/FileDownloaderTest.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/api/Connection.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/api/ConnectionException.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/api/ConnectionManager.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/api/DownloadListener.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/impl/ConnectionImpl.java create mode 100644 group02/527705641/src/com/github/fei9009/coderising0305/download/impl/ConnectionManagerImpl.java create mode 100644 group02/527705641/src/com/github/fei9009/coding2017/basic/ListTest.java delete mode 100644 group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/ArrayList.java (95%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java (95%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/Iterator.java (95%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/IteratorImp.java (100%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/LinkedList.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/List.java (95%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/Queue.java (94%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/basic/Stack.java (94%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/array/ArrayUtil.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/DownloadThread.java (97%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/FileDownloader.java (97%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/api/Connection.java (95%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionException.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/api/ConnectionManager.java (95%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/api/DownloadListener.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionImpl.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/download/impl/ConnectionManagerImpl.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/litestruts/LoginAction.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/litestruts/LogoutAction.java (96%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/litestruts/Struts.java (97%) rename group02/812350401/src/{ => main/java}/com/github/miniyk2012/coding2017/coderising/litestruts/View.java (95%) rename group02/812350401/src/{ => main/java}/utils/ArrayUtils.java (100%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/basic/test => test/java/com/github/miniyk2012/coding2017/basic}/ArrayListTest.java (57%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/basic/test => test/java/com/github/miniyk2012/coding2017/basic}/BinaryTreeNodeTest.java (97%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/basic/test => test/java/com/github/miniyk2012/coding2017/basic}/LinkedListTest.java (98%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/basic/test => test/java/com/github/miniyk2012/coding2017/basic}/ListTest.java (97%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/basic/test => test/java/com/github/miniyk2012/coding2017/basic}/QueueTest.java (92%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/basic/test => test/java/com/github/miniyk2012/coding2017/basic}/StackTest.java (92%) rename group02/812350401/src/{com/github/miniyk2012/coding2017/coderising/array/test => test/java/com/github/miniyk2012/coding2017/coderising/array}/ArrayUtilTest.java (98%) rename group02/812350401/src/test/{com/github/miniyk2012/coding2017/coderising/download/impl => java/com/github/miniyk2012/coding2017/coderising/download}/ConnectionImplTest.java (86%) rename group02/812350401/src/{ => test/java}/com/github/miniyk2012/coding2017/coderising/download/FileDownloaderTest.java (96%) rename group02/812350401/src/{ => test/java}/com/github/miniyk2012/coding2017/coderising/litestruts/StrutsTest.java (97%) rename group03/1360464792/src/test/java/rui/study/coding2017/jobs3/{ => download}/FileDownloaderTest.java (88%) create mode 100644 group03/1360464792/src/test/java/rui/study/coding2017/jobs3/download/impl/ConnectionImplTest.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/DownloadThread.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/FileDownloader.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/api/Connection.java rename {group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => group03/345943980/download-0335/src/main/java/com/coderising/download}/api/ConnectionException.java (70%) create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/api/ConnectionManager.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/api/DownloadListener.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coding/basic/ArrayList.java rename {group04/120549547/base/src => group03/345943980/download-0335/src/main/java}/com/coding/basic/BinaryTreeNode.java (100%) rename {group04/120549547/base/src => group03/345943980/download-0335/src/main/java}/com/coding/basic/Iterator.java (100%) create mode 100644 group03/345943980/download-0335/src/main/java/com/coding/basic/LinkedList.java rename {group12/446031103/src => group03/345943980/download-0335/src/main/java}/com/coding/basic/List.java (100%) create mode 100644 group03/345943980/download-0335/src/main/java/com/coding/basic/Queue.java create mode 100644 group03/345943980/download-0335/src/main/java/com/coding/basic/Stack.java create mode 100644 group03/345943980/download-0335/src/test/java/com/coderising/download/ConnectionTest.java create mode 100644 group03/345943980/download-0335/src/test/java/com/coderising/download/FileDownloaderTest.java create mode 100644 group03/345943980/download-0335/src/test/java/com/coderising/download/TestLinkedList.java create mode 100644 group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Configuration.java create mode 100644 group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ConfigurationException.java create mode 100644 group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/LoginAction.java create mode 100644 group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/ReflectionUtil.java create mode 100644 group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/Struts.java create mode 100644 group03/345943980/lite-struts-0226/src/main/java/com/coderising/teacher/litestruts/View.java create mode 100644 group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java create mode 100644 group03/345943980/lite-struts-0226/src/test/java/com/coderising/litestruts/StrutsTest1.java create mode 100644 group03/58555264/src/main/java/com/circle/collection/LinkedListV2.java create mode 100644 group03/58555264/src/main/java/com/circle/download/DownloadThread.java create mode 100644 group03/58555264/src/main/java/com/circle/download/FileDownloader.java create mode 100644 group03/58555264/src/main/java/com/circle/download/api/Connection.java create mode 100644 group03/58555264/src/main/java/com/circle/download/api/ConnectionException.java create mode 100644 group03/58555264/src/main/java/com/circle/download/api/ConnectionManager.java create mode 100644 group03/58555264/src/main/java/com/circle/download/api/DownloadListener.java create mode 100644 group03/58555264/src/main/java/com/circle/download/impl/ConnectionImpl.java create mode 100644 group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerFactory.java create mode 100644 group03/58555264/src/main/java/com/circle/download/impl/ConnectionManagerImpl.java create mode 100644 group03/58555264/src/test/java/com/circle/collection/LinkedListV2Test.java create mode 100644 group03/58555264/src/test/java/com/circle/download/FileDownloaderTest.java create mode 100644 group03/619224754/src/com/coderising/lru/LRU.java create mode 100644 group03/619224754/src/com/coding/basic/Dequeue.java create mode 100644 group03/619224754/src/test/LRUTest.java create mode 100644 group03/664269713/DataStructure/src/com/ace/coding/LinkedListTest.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/DownloadThread.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/FileDownloader.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/api/Connection.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/api/ConnectionException.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/api/ConnectionManager.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/api/DownloadListener.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionImpl.java create mode 100644 group03/664269713/DataStructure/src/com/ace/download/impl/ConnectionManagerImpl.java create mode 100644 group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/EmployeeV1.java rename {group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm => group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList}/Iterator.java (61%) create mode 100644 group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrame.java create mode 100644 group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrameTest.java create mode 100644 group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LinkedList.java create mode 100644 group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java rename {group15/1502_1617273078 => group04/1020483199/ThirdHomeWork}/src/com/coderising/litestruts/LoginAction.java (100%) create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java rename {group15/1513_121469918/HomeWork20170305 => group04/1020483199/ThirdHomeWork}/src/com/coderising/litestruts/StrutsTest.java (100%) create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java rename {group14/187114392/work_1_20170225 => group04/1020483199/ThirdHomeWork}/src/com/coding/basic/BinaryTreeNode.java (100%) rename {group12/446031103 => group04/1020483199/ThirdHomeWork}/src/com/coding/basic/Iterator.java (100%) create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java rename {group14/187114392/work_1_20170225 => group04/1020483199/ThirdHomeWork}/src/com/coding/basic/List.java (100%) create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java create mode 100644 group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java delete mode 100644 group04/120549547/base/buil.bat delete mode 100644 group04/120549547/base/src/com/coding/basic/ArrayList.java delete mode 100644 group04/120549547/base/src/com/coding/basic/LinkedList.java delete mode 100644 group04/120549547/base/src/com/coding/basic/Main.java delete mode 100644 group04/120549547/base/src/com/coding/basic/Queue.java delete mode 100644 group04/120549547/base/src/com/coding/basic/Stack.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/List.java rename {liuxin/data-structure/src => group04/120549547/code2017/src/main/java}/com/coding/basic/Stack.java (100%) create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java create mode 100644 group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java create mode 100644 group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java create mode 100644 group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java create mode 100644 group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java create mode 100644 group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java create mode 100644 group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java create mode 100644 group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java delete mode 100644 group04/120549547/my.txt create mode 100644 group04/1299310140/src/com/coderising/download/DownloadThread.java create mode 100644 group04/1299310140/src/com/coderising/download/FileDownloader.java create mode 100644 group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group04/1796244932/learn01/1.png create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java create mode 100644 group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java create mode 100644 group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java delete mode 100644 group04/349184132/Study/.classpath delete mode 100644 group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs delete mode 100644 group04/349184132/Study/bin/com/second/struts.xml delete mode 100644 group04/349184132/Study/bin/com/test/student2.xml delete mode 100644 group04/349184132/Study/bin/com/test/students.xml create mode 100644 group04/349184132/Study/src/com/coderising/download/DownloadThread.java create mode 100644 group04/349184132/Study/src/com/coderising/download/FileDownloader.java create mode 100644 group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group04/349184132/Study/src/com/coderising/download/api/Connection.java create mode 100644 group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java create mode 100644 group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java create mode 100644 group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group04/349184132/Study/src/com/linked/Iterator.java create mode 100644 group04/349184132/Study/src/com/linked/LinkedList.java create mode 100644 group04/349184132/Study/src/com/linked/List.java create mode 100644 group04/351121278/src/com/coding/download/DownloadThread.java create mode 100644 group04/351121278/src/com/coding/download/FileDownloader.java create mode 100644 group04/351121278/src/com/coding/download/FileDownloaderTest.java create mode 100644 group04/351121278/src/com/coding/download/api/Connection.java create mode 100644 group04/351121278/src/com/coding/download/api/ConnectionException.java create mode 100644 group04/351121278/src/com/coding/download/api/ConnectionManager.java create mode 100644 group04/351121278/src/com/coding/download/api/DownloadListener.java create mode 100644 group04/351121278/src/com/coding/download/impl/ConnectionImpl.java create mode 100644 group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java create mode 100644 group04/474772605/jsp/homepage.jsp create mode 100644 group04/474772605/jsp/showLogin.jsp rename {group12/382266293 => group04/474772605}/src/com/coderising/action/LoginAction.java (95%) create mode 100644 group04/474772605/src/com/coderising/action/LogoutAction.java create mode 100644 group04/474772605/src/com/coderising/action/Struts.java create mode 100644 group04/474772605/src/com/coderising/action/StrutsTest.java create mode 100644 group04/474772605/src/com/coderising/action/View.java create mode 100644 group04/474772605/src/com/coderising/array/ArrayUtil.java create mode 100644 group04/474772605/src/com/coding/basic/Node.java create mode 100644 group04/474772605/src/com/coding/basic/Testclassextends.java create mode 100644 group04/474772605/src/com/coding/iostreams/inteface.java create mode 100644 group04/474772605/src/com/coding/iostreams/readfile.java create mode 100644 group04/474772605/src/com/coding/iostreams/test.java create mode 100644 group04/474772605/test/Test.java create mode 100644 group04/474772605/test/com/coding/basic/Heros.java create mode 100644 group04/474772605/test/com/coding/basic/Test.java create mode 100644 group04/474772605/test/com/coding/basic/TestStack.java create mode 100644 group04/474772605/test/com/coding/basic/Testarray.java create mode 100644 group04/474772605/test/com/coding/basic/teest.java create mode 100644 group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group04/498654356/one/src/org/coding/four/lru/LRUPageFrame.java create mode 100644 group04/498654356/one/src/org/coding/three/download/DownloadThread.java create mode 100644 group04/498654356/one/src/org/coding/three/download/FileDownloader.java create mode 100644 group04/498654356/one/src/org/coding/three/download/api/Connection.java create mode 100644 group04/498654356/one/src/org/coding/three/download/api/ConnectionException.java create mode 100644 group04/498654356/one/src/org/coding/three/download/api/ConnectionManager.java create mode 100644 group04/498654356/one/src/org/coding/three/download/api/DownloadListener.java create mode 100644 group04/498654356/one/src/org/coding/three/download/impl/ConnectionImpl.java create mode 100644 group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java rename {group01/1814014897/zhouhui/src/week01/BasicDataStructure => group04/498654356/one/src/org/coding/three/list}/List.java (83%) create mode 100644 group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java create mode 100644 group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java create mode 100644 group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java create mode 100644 group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/DownloadListener.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/test/java/com/coding/basic/TestLinkedList.java create mode 100644 group04/821655640/learning_projects/project_basic_001/src/test/java/com/txp/temp/Test.java create mode 100644 group04/844028312/four/linklist/LRUPageFrame.java create mode 100644 group04/844028312/four/linklist/LRUPageFrameTest.java create mode 100644 group04/844028312/four/linklist/LinkedList.java create mode 100644 group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group04/844028312/four/min-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group04/844028312/four/min-jvm/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group04/844028312/three/src/com/coderising/array/ArrayUtil.java create mode 100644 group04/844028312/three/src/com/coderising/download/DownloadThread.java create mode 100644 group04/844028312/three/src/com/coderising/download/FileDownloader.java create mode 100644 group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group04/844028312/three/src/com/coderising/download/api/Connection.java create mode 100644 group04/844028312/three/src/com/coderising/download/api/ConnectionException.java create mode 100644 group04/844028312/three/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group04/844028312/three/src/com/coderising/download/api/DownloadListener.java create mode 100644 group04/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group04/844028312/three/src/com/coderising/download/impl/ConnectionManagerImpl.java rename {group15/1513_121469918/HomeWork20170305 => group04/844028312/three}/src/com/coderising/litestruts/LoginAction.java (100%) create mode 100644 group04/844028312/three/src/com/coderising/litestruts/Struts.java rename {group24/798277403/src/week2 => group04/844028312/three/src/com/coderising}/litestruts/StrutsTest.java (96%) rename {group15/1502_1617273078 => group04/844028312/three}/src/com/coderising/litestruts/View.java (100%) create mode 100644 group04/844028312/three/src/com/coding/basic/ArrayList.java create mode 100644 group04/844028312/three/src/com/coding/basic/BinaryTreeNode.java rename {group14/187114392/work_1_20170225 => group04/844028312/three}/src/com/coding/basic/Iterator.java (100%) create mode 100644 group04/844028312/three/src/com/coding/basic/LinkedList.java create mode 100644 group04/844028312/three/src/com/coding/basic/LinkedListTest.java rename {group15/1502_1617273078 => group04/844028312/three}/src/com/coding/basic/List.java (100%) create mode 100644 group04/844028312/three/src/com/coding/basic/Queue.java create mode 100644 group04/844028312/three/src/com/coding/basic/Stack.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/Utils.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java create mode 100644 group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java create mode 100644 group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java create mode 100644 group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java create mode 100644 group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java create mode 100644 group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java create mode 100644 group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java create mode 100644 group04/916758663/minijvm/src/test/java/com/example/jvm/loader/EmployeeV1.java create mode 100644 group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group05/1094051862/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java create mode 100644 group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java create mode 100644 group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java rename group05/284422826/src/com/coding2017/basic/{ => array}/ArrayList.java (100%) rename group05/284422826/src/com/{coderising => coding2017/basic}/array/ArrayUtil.java (100%) rename group05/284422826/src/com/{coderising => coding2017/basic}/array/ArrayUtilTest.java (100%) create mode 100644 group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java create mode 100644 group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java rename group05/284422826/src/com/coding2017/basic/{ => linklist}/LinkedList.java (98%) create mode 100644 group05/289326186/src/com/coderising/download/DownloadThread.java create mode 100644 group05/289326186/src/com/coderising/download/FileDownloader.java create mode 100644 group05/289326186/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group05/289326186/src/com/coderising/download/api/Connection.java create mode 100644 group05/289326186/src/com/coderising/download/api/ConnectionException.java create mode 100644 group05/289326186/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group05/289326186/src/com/coderising/download/api/DownloadListener.java create mode 100644 group05/289326186/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group05/289326186/src/com/coderising/download/impl/ConnectionManagerImpl.java delete mode 100644 group06/1378560653/src/com/coderising/array/ArrayUtil.java create mode 100644 group06/1378560653/src/com/coderising/download/DownloadThread.java create mode 100644 group06/1378560653/src/com/coderising/download/FileDownloader.java create mode 100644 group06/1378560653/src/com/coderising/download/api/Connection.java create mode 100644 group06/1378560653/src/com/coderising/download/api/ConnectionException.java create mode 100644 group06/1378560653/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group06/1378560653/src/com/coderising/download/api/DownloadListener.java create mode 100644 group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group06/1378560653/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/Configuration.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java rename group06/1378560653/src/com/coderising/litestruts/{StructsTest.java => StrutsTest.java} (97%) delete mode 100644 group06/1378560653/src/com/coderising/litestruts/structs.xml rename group06/1378560653/src/com/coding/basic/{ => array}/ArrayList.java (95%) create mode 100644 group06/1378560653/src/com/coding/basic/array/ArrayUtil.java create mode 100644 group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LinkedList.java create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java create mode 100644 group06/1454385822/src/com/coding/basic/homework_04/jvm.rar create mode 100644 group06/1454385822/src/com/coding/basic/homework_04/jvm/loader/ClassFileLoader.java create mode 100644 group06/1454385822/src/com/coding/basic/homework_04/jvm/test/ClassFileloaderTest.java create mode 100644 group06/1454385822/src/com/coding/basic/homework_04/jvm/test/EmployeeV1.java create mode 100644 group06/1454385822/src/com/coding/basic/homework_04/lru/LRUPageFrame.java create mode 100644 group06/1454385822/src/com/coding/basic/homework_04/lru/LRUPageFrameTest.java create mode 100644 group06/2415980327/CodeSE01/down2.png create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/LinkedList.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/basic/List.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/DownloadThread.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloader.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/FileDownloaderTest.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/Connection.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionException.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/ConnectionManager.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/api/DownloadListener.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionImpl.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/se03/download/impl/ConnectionManagerImpl.java create mode 100644 group06/2415980327/CodeSE01/src/com/pxshuo/test/ConnectTest.java create mode 100644 group06/2415980327/CodeSE01/src/test/com/pxshuo/se03/array/LinkedListUntilTest.java create mode 100644 "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" create mode 100644 "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" delete mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedList.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/DownloadThread.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/FileDownloader.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/Connection.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionException.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/ConnectionManager.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/api/DownloadListener.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionImpl.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/downloader/impl/ConnectionManagerImpl.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/jvm/ClassFileLoader.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrame.java create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/linkedlist/LinkedList.java rename group06/263050006/src/main/java/com/github/chaoswang/learning/java/{collection/myown/MyStack.java => stack/Stack.java} (90%) create mode 100644 group06/263050006/src/main/java/com/github/chaoswang/learning/java/stack/StackUtil.java delete mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/collection/myown/MyLinkedListTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/downloader/FileDownloaderTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/ClassFileloaderTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/jvm/EmployeeV1.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LRUPageFrameTest.java create mode 100644 group06/263050006/src/test/java/com/github/chaoswang/learning/java/linkedlist/LinkedListTest.java create mode 100644 group06/547958234/src/com/coderising/array/ArrayUtil.java create mode 100644 group06/547958234/src/com/coderising/download/DownloadThread.java create mode 100644 group06/547958234/src/com/coderising/download/FileDownloader.java rename {group12/446031103 => group06/547958234}/src/com/coderising/download/FileDownloaderTest.java (100%) create mode 100644 group06/547958234/src/com/coderising/download/api/Connection.java create mode 100644 group06/547958234/src/com/coderising/download/api/ConnectionException.java create mode 100644 group06/547958234/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group06/547958234/src/com/coderising/download/api/DownloadListener.java create mode 100644 group06/547958234/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group06/547958234/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group06/547958234/src/com/coderising/litestruts/LoginAction.java create mode 100644 group06/547958234/src/com/coderising/litestruts/Struts.java rename {group15/1521_653895972/src/com/coding => group06/547958234/src/com}/coderising/litestruts/StrutsTest.java (96%) rename {group15/1513_121469918/HomeWork20170305 => group06/547958234}/src/com/coderising/litestruts/View.java (100%) create mode 100644 group06/949319266/Test/src/com/ecust/test/GArrayList.java create mode 100644 group06/949319266/Test/src/com/ecust/test/GIterator.java create mode 100644 group06/949319266/Test/src/com/ecust/test/GList.java rename group06/{1378560653 => 949319266/homework}/src/com/coding/basic/LinkedList.java (77%) create mode 100644 group06/949319266/homework/src/com/coding/basic/List.java create mode 100644 "group06/949319266/homework/src/\346\226\207\347\253\240\344\270\211" create mode 100644 group06/949319266/homework003/src/DownloadThread.java create mode 100644 group06/949319266/homework003/src/FileDownloader.java create mode 100644 group06/949319266/homework003/src/FileDownloaderTest.java create mode 100644 group06/949319266/homework003/src/com/coderising/download/api/Connection.java create mode 100644 group06/949319266/homework003/src/com/coderising/download/api/ConnectionException.java create mode 100644 group06/949319266/homework003/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group06/949319266/homework003/src/com/coderising/download/api/DownloadListener.java create mode 100644 group06/949319266/homework003/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group06/949319266/homework003/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/Configuration.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationException.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/LoginAction.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/ReflectionUtilTest.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/Struts.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group06/949319266/homework03/src/src/com/coderising/litestruts/View.java create mode 100644 "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" create mode 100644 group06/949319266/homework04/src/ClassFileLoader/ClassFileLoader.java create mode 100644 group06/949319266/homework04/src/ClassFileLoader/ClassFileloaderTest.java create mode 100644 group06/949319266/homework04/src/ClassFileLoader/EmployeeV1.java create mode 100644 group06/949319266/homework04/src/ClassFileLoader/LRUPageFrame.java create mode 100644 group06/949319266/homework04/src/Test/ClassFileloaderTest.java create mode 100644 group06/949319266/homework04/src/Test/LRUPageFrameTest.java create mode 100644 "group06/949319266/homework04/src/\346\226\207\347\253\2404" create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/Configuration.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationException.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/LoginAction.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/ReflectionUtilTest.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/Struts.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group06/949319266/lite-struts2/src/com/coderising/litestruts/View.java create mode 100644 group08/1144989424/secondPractice/readme.md create mode 100644 group08/1144989424/thirdPractice/readme.md create mode 100644 group08/1144989424/thirdPractice/src/download/DownloadThread.java create mode 100644 group08/1144989424/thirdPractice/src/download/FileDownloader.java rename {group01/895457260/code => group08/1144989424/thirdPractice}/src/download/FileDownloaderTest.java (69%) create mode 100644 group08/1144989424/thirdPractice/src/download/api/Connection.java create mode 100644 group08/1144989424/thirdPractice/src/download/api/ConnectionException.java create mode 100644 group08/1144989424/thirdPractice/src/download/api/ConnectionManager.java create mode 100644 group08/1144989424/thirdPractice/src/download/api/DownloadListener.java create mode 100644 group08/1144989424/thirdPractice/src/download/impl/ConnectionImpl.java create mode 100644 group08/1144989424/thirdPractice/src/download/impl/ConnectionManagerImpl.java create mode 100644 group08/1144989424/thirdPractice/src/download/impl/DownloadListenerImpl.java create mode 100644 group08/1144989424/thirdPractice/src/linkedlist/MyIterator.java create mode 100644 group08/1144989424/thirdPractice/src/linkedlist/MyLinkedList.java create mode 100644 group08/1144989424/thirdPractice/src/linkedlist/MyList.java create mode 100644 group08/1425809544/03-05/com/array/ArrayUtil.java create mode 100644 group08/1425809544/03-05/com/array/ArrayUtilTest.java create mode 100644 "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" create mode 100644 group08/1425809544/03-12/code/com/xyy/baselinked/Iterator.java create mode 100644 group08/1425809544/03-12/code/com/xyy/baselinked/LinkedList.java create mode 100644 group08/1425809544/03-12/code/com/xyy/baselinked/List.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/DownloadThread.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/FileDownloader.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/FileDownloaderTest.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/api/Connection.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/api/ConnectionException.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/api/ConnectionManager.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/api/DownloadListener.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionImpl.java create mode 100644 group08/1425809544/03-12/code/com/xyy/download/impl/ConnectionManagerImpl.java rename group08/1425809544/1425809544.md => "group08/1425809544/1425809544-\345\215\232\345\256\242\345\234\260\345\235\200.md" (67%) create mode 100644 group08/286060098/3-27/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group08/286060098/3-27/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group08/286060098/3-27/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group08/286060098/3-27/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group08/619057560/4-2/code/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group08/619057560/4-2/code/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java delete mode 100644 group08/README.md delete mode 100644 "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" create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/shoppingcart.data create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170205.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170212.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/github/eulerlcs/jmr/challenge/zzz/master170219/Try170219.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/BatchDownloadFile.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/DownloadFile.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/download/SaveItemFile.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/entity/DownloadInfo.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtils.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/DownloadUtilsTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-11-challenge/src/main/java/com/hoo/util/LogUtils.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => jmr-51-liuxin-question/src/main/java/com/coderising/download}/api/Connection.java (91%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/ConnectionException.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => jmr-51-liuxin-question/src/main/java/com/coderising/download}/api/ConnectionManager.java (80%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/api/DownloadListener.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/core/DownloadThread.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => jmr-51-liuxin-question/src/main/java/com/coderising/download/core}/FileDownloader.java (87%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => jmr-51-liuxin-question/src/main/java/com/coderising/download}/impl/ConnectionImpl.java (73%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java rename {group17/1264835468/src/assignment2_26 => group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts}/LoginAction.java (91%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/Struts.java rename {group17/1264835468/src/assignment2_26 => group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts}/View.java (87%) rename {group15/1513_121469918/HomeWork01/src/coding => group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic}/BinaryTreeNode.java (54%) rename {group15/1513_121469918/HomeWork20170305/src => group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java}/com/coding/basic/Iterator.java (81%) rename {group16/1012075117/DataStructure219/src/com/stackwei/DataStructure => group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic}/List.java (83%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Queue.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Stack.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayList.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/array/ArrayUtil.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/linklist/LinkedList.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170226-collection => jmr-51-liuxin-question}/src/main/resources/.gitkeep (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/test/java/com/github/eulerlcs/jmr/multiDL => jmr-51-liuxin-question/src/test/java/com/coderising/download/core}/FileDownloaderTest.java (80%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/jvm/loader/EmployeeV1.java rename {group17/1264835468/src/assignment2_26 => group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts}/StrutsTest.java (94%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coding/basic/linklist/LRUPageFrameTest.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170226-collection => jmr-51-liuxin-question}/src/test/resources/.gitkeep (100%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/basic/LinkedList.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/basic/List.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/api/Connection.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/api/ConnectionException.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/api/ConnectionManager.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/api/DownloadListener.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/core/DownloadThread.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/core/FileDownloader.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Configuration.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ConfigurationException.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/LoginAction.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/Struts.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/main/java/com/coderising/litestruts/View.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts/src/main/java => jmr-52-liuxin-answer/src/main/resources}/.gitkeep (100%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/basic/LinkedListTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/api/ConnectionTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/download/core/FileDownloaderTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/ReflectionUtilTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-52-liuxin-answer/src/test/java/com/coderising/litestruts/StrutsTest.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts/src/test/java => jmr-52-liuxin-answer/src/test/resources}/.gitkeep (100%) delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/pom.xml delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/resources/log4j.xml delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/data/struts.xml delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/resources/log4j.xml delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/impl/ConnectionManagerImpl.java delete mode 100644 group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/resources/log4j.xml rename group09/41689722.eulerlcs/2.code/{jmr-61-170226-collection/src/main/java/com/github/eulerlcs/jmr/collection/core => jmr-61-collection/src/main/java/com/github/eulerlcs/jmr/algorithm}/ArrayList.java (99%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts/src/test => jmr-61-collection/src/main}/resources/.gitkeep (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170226-collection/src/test/java/com/github/eulerlcs/jmr/collection/core => jmr-61-collection/src/test/java/com/github/eulerlcs/jmr/algorithm}/TestArrayList.java (86%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/data => jmr-61-collection/src/test/resources}/.gitkeep (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/test/resources => jmr-62-litestruts/src/main/java}/.gitkeep (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts/src/main/java/com/github/eulerlcs/jmr/litestruts => jmr-62-litestruts/src/main/java/com/github/eulerlcs/jmr}/algorithm/ArrayUtil.java (99%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LoginAction.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/action/LogoutAction.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/core/Struts.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/core/View.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsAction.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionResult.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsActionRulerSet.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsConfig.java (100%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/main/java/com/github/eulerlcs/jmr/litestruts/degister/StrutsDigester.java (100%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/java/.gitkeep rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts/src/test/java/com/github/eulerlcs/jmr/litestruts/util => jmr-62-litestruts/src/test/java/com/github/eulerlcs/jmr/algorithm}/ArrayUtilTest.java (97%) rename group09/41689722.eulerlcs/2.code/{jmr-61-170305-litestruts => jmr-62-litestruts}/src/test/java/com/github/eulerlcs/jmr/litestruts/core/StrutsTest.java (100%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-62-litestruts/src/test/resources/.gitkeep create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/data/.gitkeep create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/Iterator.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/LinkedList.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/algorithm/List.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/Connection.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionException.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/ConnectionManager.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/api/DownloadListener.java rename group09/41689722.eulerlcs/2.code/{jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL => jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core}/DownloadThread.java (72%) create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/core/FileDownloader.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionImpl.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/main/java/com/github/eulerlcs/jmr/download/impl/ConnectionManagerImpl.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/java/com/github/eulerlcs/jmr/download/core/FileDownloaderTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-63-download/src/test/resources/.gitkeep create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/data/.gitkeep create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrame.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/main/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileLoader.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/algorithm/LRUPageFrameTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/ClassFileloaderTest.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/java/com/github/eulerlcs/jmr/jvm/loader/EmployeeV1.java create mode 100644 group09/41689722.eulerlcs/2.code/jmr-64-minijvm/src/test/resources/.gitkeep create mode 100644 group09/41689722.eulerlcs/5.settingfile/eclipsev45.epf create mode 100644 group09/610673813/src/coding/week02/array/ArrayUtil.java create mode 100644 group09/610673813/src/coding/week02/array/ArrayUtilTest.java create mode 100644 group09/610673813/src/coding/week03/DownloadThread.java create mode 100644 group09/610673813/src/coding/week03/FileDownloader.java create mode 100644 group09/610673813/src/coding/week03/download/api/Connection.java create mode 100644 group09/610673813/src/coding/week03/download/api/ConnectionException.java create mode 100644 group09/610673813/src/coding/week03/download/api/ConnectionManager.java create mode 100644 group09/610673813/src/coding/week03/download/api/DownloadListener.java create mode 100644 group09/610673813/src/coding/week03/download/impl/ConnectionImpl.java create mode 100644 group09/610673813/src/coding/week03/download/impl/ConnectionManagerImpl.java rename {group01/1814014897/zhouhui/src/week01/BasicDataStructure => group09/790466157/src/com/coderising/linkedlist}/Iterator.java (70%) create mode 100644 group09/790466157/src/com/coderising/linkedlist/LinkedList.java create mode 100644 group09/790466157/src/com/coderising/linkedlist/LinkedListTest.java create mode 100644 group09/790466157/src/com/coderising/linkedlist/List.java create mode 100644 group09/790466157/src/com/coderising/litestruts/Configuration.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ConfigurationException.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java delete mode 100644 group09/790466157/src/com/coderising/litestruts/SAX.java delete mode 100644 group09/790466157/src/com/coderising/litestruts/SAXmain.java create mode 100644 group10/205301442/src/api/Connection.java create mode 100644 group10/205301442/src/api/ConnectionException.java create mode 100644 group10/205301442/src/api/ConnectionManager.java create mode 100644 group10/205301442/src/api/DownloadListener.java create mode 100644 group10/205301442/src/com/coding/week1/LinkedList1.java create mode 100644 group10/205301442/src/download/DownloadThread.java create mode 100644 group10/205301442/src/download/FileDownloader.java create mode 100644 group10/205301442/src/download/FileDownloaderTest.java create mode 100644 group10/205301442/src/download/api/Connection.java create mode 100644 group10/205301442/src/download/api/ConnectionException.java create mode 100644 group10/205301442/src/download/api/ConnectionManager.java create mode 100644 group10/205301442/src/download/api/DownloadListener.java create mode 100644 group10/205301442/src/download/impl/ConnectionImpl.java create mode 100644 group10/205301442/src/download/impl/ConnectionManagerImpl.java create mode 100644 group10/205301442/src/download/impl/DoloadListenerImpl.java create mode 100644 group10/205301442/src/impl/ConnectionImpl.java create mode 100644 group10/205301442/src/impl/ConnectionManagerImpl.java create mode 100644 group10/205301442/src/impl/DoloadListenerImpl.java create mode 100644 group10/904627477/src/com/coding/basic/LRUPageFrame.java create mode 100644 group10/904627477/src/com/coding/litestruts/Action.java create mode 100644 group10/904627477/src/com/coding/litestruts/Result.java create mode 100644 group10/904627477/src/com/coding/litestruts/StrutsXMLParser.java create mode 100644 group10/904627477/src/com/coding/test/ClassFileloaderTest.java create mode 100644 group10/904627477/src/com/coding/test/EmployeeV1.java create mode 100644 group10/904627477/src/com/coding/test/LRUPageFrameTest.java create mode 100644 group10/904627477/src/com/conding/jvm/loader/ClassFileLoader.java create mode 100644 group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java rename group12/2258659044/zj-2017/src/com/coding/basic/{ => array}/ArrayList.java (94%) rename group12/2258659044/zj-2017/src/com/{coderising => coding/basic}/array/ArrayUtil.java (94%) create mode 100644 group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java rename group12/2258659044/zj-2017/src/com/coding/basic/{ => linklist}/LinkedList.java (94%) create mode 100644 group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/ClassFileloaderTest.java create mode 100644 group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/EmployeeV1.java rename group12/2258659044/zj-2017/src/test/com/coding/basic/{ => array}/ArrayListTest.java (96%) rename group12/2258659044/zj-2017/src/test/com/{coderising => coding/basic}/array/ArrayUtilTest.java (91%) create mode 100644 group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LRUPageFrameTest.java rename group12/2258659044/zj-2017/src/test/com/coding/basic/{ => linklist}/LinkedListTest.java (93%) create mode 100644 group12/247565311/week5/ClassFileLoader.java create mode 100644 group12/247565311/week5/ClassFileLoaderTest.java create mode 100644 group12/247565311/week5/EmployeeV1.java create mode 100644 group12/247565311/week5/LRU.java create mode 100644 group12/247565311/week5/LRUTest.java create mode 100644 group12/349166103/LRUPageFrame.java rename group12/377401843/learning/src/main/java/com/zhaogd/{collection => array}/ArrayList.java (87%) create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java rename group12/377401843/learning/src/main/java/com/zhaogd/collection/{ => linkedlist}/LinkedList.java (94%) rename group12/377401843/learning/src/main/java/com/zhaogd/collection/{ => stack}/Stack.java (80%) create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileParser.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/ClassFileloaderTest.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java create mode 100644 group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java create mode 100644 group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group12/382266293/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group12/382266293/src/com/coderising/litestruts/LoginAction.java create mode 100644 group12/446031103/src/com/coderising/download/test/ConnectionTest.java create mode 100644 group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java create mode 100644 group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group12/446031103/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group12/446031103/src/com/coderising/litestruts/Configuration.java create mode 100644 group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java rename group12/446031103/src/com/{coding/basic => datastructure/array}/ArrayList.java (87%) rename group12/446031103/src/com/{coderising => datastructure}/array/ArrayUtil.java (51%) rename group12/446031103/src/com/{coderising => datastructure}/array/ArrayUtilTest.java (98%) rename group12/446031103/src/com/{coding => datastructure}/basic/BinaryTreeNode.java (96%) create mode 100644 group12/446031103/src/com/datastructure/basic/Iterator.java create mode 100644 group12/446031103/src/com/datastructure/basic/List.java rename group12/446031103/src/com/{coding => datastructure}/basic/Queue.java (93%) rename group12/446031103/src/com/{coding => datastructure}/basic/Stack.java (94%) create mode 100644 group12/446031103/src/com/datastructure/linklist/LRUPageFrame.java create mode 100644 group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java rename group12/446031103/src/com/{coding/basic => datastructure/linklist}/LinkedList.java (74%) create mode 100644 group12/563253496/week3_file_download/src/com/coderising/array/ArrayUtil.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/api/Connection.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/api/DownloadListener.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/litestruts/LoginAction.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/litestruts/Struts.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group12/563253496/week3_file_download/src/com/coderising/litestruts/View.java create mode 100644 group12/563253496/week3_file_download/src/com/coding/basic/ArrayList.java create mode 100644 group12/563253496/week3_file_download/src/com/coding/basic/BinaryTreeNode.java rename {group15/1502_1617273078 => group12/563253496/week3_file_download}/src/com/coding/basic/Iterator.java (100%) rename {group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm => group12/563253496/week3_file_download/src/com/coding/basic}/LinkedList.java (98%) rename {group15/1513_121469918/HomeWork20170305 => group12/563253496/week3_file_download}/src/com/coding/basic/List.java (100%) create mode 100644 group12/563253496/week3_file_download/src/com/coding/basic/Queue.java create mode 100644 group12/563253496/week3_file_download/src/com/coding/basic/Stack.java create mode 100644 group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java rename {group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader => group12/563253496/week4_jvm1/src/com/coderising/jvm/test}/ClassFileloaderTest.java (66%) create mode 100644 group12/563253496/week4_jvm1/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group12/563253496/week4_lru/src/LRUPageFrame.java create mode 100644 group12/563253496/week4_lru/src/LRUPageFrameTest.java create mode 100644 group13/2729382520/L4/src/io/github/vxzh/jvm/loader/ClassFileLoader.java create mode 100644 group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java create mode 100644 group13/2729382520/L4/src/io/github/vxzh/jvm/test/EmployeeV1.java create mode 100644 group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrame.java create mode 100644 group13/2729382520/L4/src/io/github/vxzh/lru/LRUPageFrameTest.java create mode 100644 group13/2931408816/lesson4/build.gradle create mode 100644 group13/2931408816/lesson4/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/BinaryTreeNode.java rename {group15/1521_653895972/src => group13/2931408816/lesson4/src/main/java}/com/coding/basic/Iterator.java (100%) rename {group15/1521_653895972/src => group13/2931408816/lesson4/src/main/java}/com/coding/basic/List.java (100%) create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/Queue.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/Stack.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayList.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/array/ArrayUtil.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group13/2931408816/lesson4/src/main/java/com/coding/basic/linklist/LinkedList.java create mode 100644 group13/2931408816/lesson4/src/test/java/com/coderising/jvm/loader/ClassFileloaderTest.java create mode 100644 group13/2931408816/lesson4/src/test/java/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group13/413007522/dataStructure/MyArrayList.java create mode 100644 group13/413007522/dataStructure/MyBinaryTree.java create mode 100644 group13/413007522/dataStructure/MyIterator.java create mode 100644 group13/413007522/dataStructure/MyLinkedList.java create mode 100644 group13/413007522/dataStructure/MyList.java create mode 100644 group13/413007522/dataStructure/MyQueue.java create mode 100644 group13/413007522/dataStructure/MyStack.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadStartup.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadTask.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/DownloadThread.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloader.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/FileDownloaderTest.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/api/Connection.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionException.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/api/ConnectionManager.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/api/DownloadListener.java create mode 100644 group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionImpl.java rename {group24/798277403/src/week3 => group13/413007522/lesson03/src/main/java/cn/xl/c3}/impl/ConnectionManagerImpl.java (56%) create mode 100644 group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrame.java create mode 100644 group13/413007522/lesson04/src/main/java/cn/xl/basic/linklist/LRUPageFrameTest.java create mode 100644 group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/ClassFileLoader.java create mode 100644 group13/413007522/lesson04/src/main/java/cn/xl/jvm/loader/EmployeeV1.java create mode 100644 group13/413007522/lesson04/src/test/java/jvm/loader/ClassFileloaderTest.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/DownloadThread.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloader.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/FileDownloaderTest.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/LinkedListTest.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/api/Connection.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionException.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/api/ConnectionManager.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/api/DownloadListener.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/api/LinkedList.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionImpl.java create mode 100644 group14/1091149131/2017JavaPro/src/com/m0312/download/impl/ConnectionManagerImpl.java rename group14/187114392/{work_1_20170225 => homework}/ReadMe.md (100%) rename group14/187114392/{work_1_20170225 => homework}/src/Main.java (100%) create mode 100644 group14/187114392/homework/src/com/array/ArrayUtil.java create mode 100644 group14/187114392/homework/src/com/coderising/download/DownloadThread.java create mode 100644 group14/187114392/homework/src/com/coderising/download/FileDownloader.java create mode 100644 group14/187114392/homework/src/com/coderising/download/FileDownloader_real.java create mode 100644 group14/187114392/homework/src/com/coderising/download/api/Connection.java create mode 100644 group14/187114392/homework/src/com/coderising/download/api/ConnectionException.java create mode 100644 group14/187114392/homework/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group14/187114392/homework/src/com/coderising/download/api/DownloadListener.java create mode 100644 group14/187114392/homework/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group14/187114392/homework/src/com/coderising/download/impl/ConnectionManagerImpl.java rename group14/187114392/{work_1_20170225 => homework}/src/com/coding/basic/ArrayList.java (100%) create mode 100644 group14/187114392/homework/src/com/coding/basic/BinaryTreeNode.java create mode 100644 group14/187114392/homework/src/com/coding/basic/Iterator.java rename group14/187114392/{work_1_20170225 => homework}/src/com/coding/basic/LinkedList.java (100%) rename {group04/120549547/base => group14/187114392/homework}/src/com/coding/basic/List.java (99%) rename group14/187114392/{work_1_20170225 => homework}/src/com/coding/basic/Queue.java (100%) rename group14/187114392/{work_1_20170225 => homework}/src/com/coding/basic/Stack.java (100%) rename group14/187114392/{work_1_20170225 => homework}/test/ArrayList_Test.java (100%) create mode 100644 group14/187114392/homework/test/FileDownloaderTest.java rename group14/187114392/{work_1_20170225 => homework}/test/LinkedList_Test.java (100%) rename group14/187114392/{work_1_20170225 => homework}/test/Queue_Test.java (100%) rename group14/187114392/{work_1_20170225 => homework}/test/Stack_Test.java (100%) delete mode 100644 group14/187114392/work_1_20170225/.classpath delete mode 100644 group14/187114392/work_1_20170225/.gitignore delete mode 100644 group14/187114392/work_1_20170225/.idea/.name delete mode 100644 group14/187114392/work_1_20170225/.idea/compiler.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/copyright/profiles_settings.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/encodings.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/junitgenerator-prj-settings.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/misc.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/modules.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/uiDesigner.xml delete mode 100644 group14/187114392/work_1_20170225/.idea/work_1_20170225.iml delete mode 100644 group14/187114392/work_1_20170225/.idea/workspace.xml delete mode 100644 group14/187114392/work_1_20170225/.project delete mode 100644 group14/187114392/work_1_20170225/.settings/org.eclipse.jdt.core.prefs delete mode 100644 group14/187114392/work_1_20170225/2017Learning.iml create mode 100644 group14/598808350/2017project/src/com/coderising/download/DownloadThread.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/FileDownloader.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/api/Connection.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/api/ConnectionException.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/api/DownloadListener.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group14/598808350/2017project/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group14/598808350/2017project/src/com/coderising/linkedlist/LinkedList.java create mode 100644 group14/598808350/2017project/src/org/comm/util/IntegerUtil.java create mode 100644 group14/598808350/2017project/src/org/download/DownImg.java rename group15/1502_1617273078/{ => data-structure}/src/com/coderising/array/ArrayUtil.java (100%) rename group15/1502_1617273078/{ => data-structure}/src/com/coderising/array/ArrayUtilTest.java (100%) create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/DownloadThread.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/FileDownloader.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/api/Connection.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/api/ConnectionException.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/api/DownloadListener.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/litestruts/LoginAction.java rename group15/1502_1617273078/{ => data-structure}/src/com/coderising/litestruts/Struts.java (100%) rename group15/1502_1617273078/{ => data-structure}/src/com/coderising/litestruts/StrutsTest.java (100%) create mode 100644 group15/1502_1617273078/data-structure/src/com/coderising/litestruts/View.java rename group15/1502_1617273078/{ => data-structure}/src/com/coding/basic/ArrayList.java (100%) create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/Iterator.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/LinkedList.java rename group15/1502_1617273078/{src/com/coding/basic/LinkedList.java => data-structure/src/com/coding/basic/LinkedListbak.java} (96%) create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/List.java rename group15/1502_1617273078/{ => data-structure}/src/com/coding/basic/Queue.java (88%) rename group15/1502_1617273078/{ => data-structure}/src/com/coding/basic/Stack.java (100%) create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/linklist/LinkedList.java create mode 100644 group15/1502_1617273078/data-structure/src/com/coding/basic/test.java create mode 100644 group15/1502_1617273078/data-structure/src/com/testself/testss.java create mode 100644 group15/1502_1617273078/data-structure/src/test/com/coding/basic/LinkedListTest.java create mode 100644 group15/1502_1617273078/data-structure/src/test/com/coding/basic/LinkedListbakTest.java create mode 100644 group15/1502_1617273078/data-structure/test.jpg create mode 100644 group15/1502_1617273078/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group15/1502_1617273078/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java rename {group24/798277403/src/week4 => group15/1502_1617273078/mini-jvm/src/com/coderising/jvm}/test/EmployeeV1.java (88%) delete mode 100644 group15/1502_1617273078/src/com/coderising/litestruts/struts.xml create mode 100644 group15/1503_1311822904/downland&LinkedList/LinkedList.java create mode 100644 group15/1503_1311822904/downland&LinkedList/LinkedListTest.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/DownloadThread.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/FileDownloader.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/FileDownloaderTest.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/api/Connection.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/api/ConnectionException.java rename {group24/798277403/src/week3 => group15/1503_1311822904/downland&LinkedList/src}/api/ConnectionManager.java (90%) rename {group24/798277403/src/week3 => group15/1503_1311822904/downland&LinkedList/src}/api/DownloadListener.java (78%) create mode 100644 group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionImpl.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionManagerImpl.java create mode 100644 group15/1503_1311822904/downland&LinkedList/src/impl/URLConnectionDownloader.java create mode 100644 group15/1507_977996067/src/task3/download/DownloadThread.java create mode 100644 group15/1507_977996067/src/task3/download/FileDownloader.java create mode 100644 group15/1507_977996067/src/task3/download/FileDownloaderTest.java create mode 100644 group15/1507_977996067/src/task3/download/api/Connection.java create mode 100644 group15/1507_977996067/src/task3/download/api/ConnectionException.java create mode 100644 group15/1507_977996067/src/task3/download/api/ConnectionManager.java create mode 100644 group15/1507_977996067/src/task3/download/api/DownloadListener.java create mode 100644 group15/1507_977996067/src/task3/download/impl/ConnectionImpl.java create mode 100644 group15/1507_977996067/src/task3/download/impl/ConnectionManagerImpl.java create mode 100644 group15/1507_977996067/src/task3/linkedlist/MyLinkedList.java create mode 100644 group15/1507_977996067/src/task3/linkedlist/MyLinkedListTest.java create mode 100644 group15/1507_977996067/src/task4/loader/ClassFileLoader.java create mode 100644 group15/1507_977996067/src/task4/loader/ClassFileloaderTest.java create mode 100644 group15/1507_977996067/src/task4/loader/EmployeeV1.java create mode 100644 group15/1507_977996067/src/task4/lru/LRUPageFrame.java create mode 100644 group15/1507_977996067/src/task4/lru/LRUPageFrameTest.java create mode 100644 group15/1510_739253131/README.md create mode 100644 group15/1510_739253131/demo1.jpg create mode 100644 group15/1510_739253131/src/com/bruce/homework0226/BinaryTreeNode.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0226/IteratorV00.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0226/LinkedListV01.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/Configuration.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/ConfigurationTest.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/LoginAction.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtil.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtilTest.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/Struts.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/StrutsTest.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0305/demostruts/View.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/DownloadThread.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloader.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloaderTest.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/api/Connection.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionException.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionManager.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/api/DownloadListener.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionImpl.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionManagerImpl.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/linkedlist/LinkedListV02.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadFileMultiThread.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadTest.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0402/jvm/loader/ClassFileLoader.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0402/jvm/test/ClassFileloaderTest.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0402/jvm/test/EmployeeV1.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0402/lru/LRUPageFrame.java create mode 100644 group15/1510_739253131/src/com/bruce/homework0402/lru/LRUPageFrameTest.java create mode 100644 "group15/1511_714512544/out/production/1511_714512544/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" create mode 100644 group15/1511_714512544/src/com/coderising/download/Demo.java create mode 100644 group15/1511_714512544/src/com/coderising/download/DownloadThread.java create mode 100644 group15/1511_714512544/src/com/coderising/download/FileDownloader.java create mode 100644 group15/1511_714512544/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group15/1511_714512544/src/com/coderising/download/api/Connection.java create mode 100644 group15/1511_714512544/src/com/coderising/download/api/ConnectionException.java create mode 100644 group15/1511_714512544/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group15/1511_714512544/src/com/coderising/download/api/DownloadListener.java create mode 100644 group15/1511_714512544/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group15/1511_714512544/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 "group15/1511_714512544/src/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" create mode 100644 group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/test/EmployeeV1.java create mode 100644 group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coding/basic/linklist/LRUPageFrame.java create mode 100644 group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coding/basic/linklist/LRUPageFrameTest.java rename group15/1513_121469918/{HomeWork01/src/coding => HomeWork/src/task0228/coding/basic}/ArrayList.java (71%) rename group15/1513_121469918/{HomeWork20170305/src/com => HomeWork/src/task0228}/coding/basic/BinaryTreeNode.java (96%) rename group15/1513_121469918/{HomeWork01/src/coding => HomeWork/src/task0228/coding/basic}/Iterator.java (77%) rename group15/1513_121469918/{HomeWork01/src/coding => HomeWork/src/task0228/coding/basic}/LinkedList.java (99%) create mode 100644 group15/1513_121469918/HomeWork/src/task0228/coding/basic/List.java rename group15/1513_121469918/{HomeWork20170305/src/com => HomeWork/src/task0228}/coding/basic/Queue.java (94%) rename group15/1513_121469918/{HomeWork01/src/coding => HomeWork/src/task0228/coding/basic}/Stack.java (95%) rename group15/1513_121469918/{HomeWork20170305/src/com/coderising => HomeWork/src/task0305/coding/basic}/array/ArrayUtil.java (96%) create mode 100644 group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/LoginAction.java rename group15/1513_121469918/{HomeWork20170305/src/com/coderising => HomeWork/src/task0305/conderising}/litestruts/Struts.java (94%) create mode 100644 group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/StrutsTest.java create mode 100644 group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/View.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/DownloadThread.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloader.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloaderTest.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/Connection.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionException.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionManager.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/DownloadListener.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionImpl.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group15/1513_121469918/HomeWork/src/task0312/coding/basic/linkedlist/LinkedList.java delete mode 100644 group15/1513_121469918/HomeWork01/.classpath delete mode 100644 group15/1513_121469918/HomeWork01/.gitignore delete mode 100644 group15/1513_121469918/HomeWork01/.project delete mode 100644 group15/1513_121469918/HomeWork01/.settings/org.eclipse.core.resources.prefs delete mode 100644 group15/1513_121469918/HomeWork01/.settings/org.eclipse.jdt.core.prefs delete mode 100644 group15/1513_121469918/HomeWork01/src/coding/Queue.java delete mode 100644 group15/1513_121469918/HomeWork20170305/.classpath delete mode 100644 group15/1513_121469918/HomeWork20170305/.project delete mode 100644 group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.core.resources.prefs delete mode 100644 group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.jdt.core.prefs delete mode 100644 group15/1513_121469918/HomeWork20170305/bin/com/coderising/litestruts/struts.xml delete mode 100644 group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/struts.xml delete mode 100644 group15/1513_121469918/HomeWork20170305/src/com/coding/basic/ArrayList.java delete mode 100644 group15/1513_121469918/HomeWork20170305/src/com/coding/basic/LinkedList.java delete mode 100644 group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Stack.java delete mode 100644 group15/1515_337959725/.settings/org.eclipse.jdt.core.prefs create mode 100644 group15/1515_337959725/src/com/coderising/download/DownloadThread.java create mode 100644 group15/1515_337959725/src/com/coderising/download/FileDownloader.java create mode 100644 group15/1515_337959725/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group15/1515_337959725/src/com/coderising/download/api/Connection.java create mode 100644 group15/1515_337959725/src/com/coderising/download/api/ConnectionException.java create mode 100644 group15/1515_337959725/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group15/1515_337959725/src/com/coderising/download/api/DownloadListener.java create mode 100644 group15/1515_337959725/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group15/1515_337959725/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group15/1515_337959725/src/com/coding/basic/SingleLinkedList.java create mode 100644 group15/1517_279137987/src/my/collection/linear/LinkedList.java create mode 100644 group15/1517_279137987/src/my/collection/linear/LinkedListTest.java delete mode 100644 group15/1521_653895972/src/com/coding/coderising/litestruts/struts.xml rename group15/1521_653895972/src/{com/coding/basic/ArrayList.java => task1/basic/WArrayList.java} (83%) rename group15/1521_653895972/src/{com/coding/basic/BinaryTreeNode.java => task1/basic/WBinaryTreeNode.java} (97%) create mode 100644 group15/1521_653895972/src/task1/basic/WIterator.java rename group15/1521_653895972/src/{com/coding/basic/LinkedList.java => task1/basic/WLinkedList.java} (53%) create mode 100644 group15/1521_653895972/src/task1/basic/WList.java rename group15/1521_653895972/src/{com/coding/basic/Queue.java => task1/basic/WQueue.java} (89%) rename group15/1521_653895972/src/{com/coding/basic/Stack.java => task1/basic/WStack.java} (90%) rename group15/1521_653895972/src/{com/coding/basic => task1/test}/BasicTest.java (92%) create mode 100644 group15/1521_653895972/src/task1/test/WLinkedListTest.java rename group15/1521_653895972/src/{com/coding/coderising => task2}/array/ArrayUtilTest.java (98%) rename group15/1521_653895972/src/{com/coding/coderising => task2}/array/SimpleArrayUtil.java (99%) rename group15/1521_653895972/src/{com/coding/coderising => task2}/litestruts/LoginAction.java (95%) rename group15/1521_653895972/src/{com/coding/coderising => task2}/litestruts/Struts.java (99%) rename group15/1521_653895972/src/{com/coding/coderising => task2}/litestruts/View.java (91%) create mode 100644 group15/1521_653895972/src/task2/test/StrutsTest.java create mode 100644 group15/1521_653895972/src/task3/basic/WLinkedList.java create mode 100644 group15/1521_653895972/src/task3/download/DownloadThread.java create mode 100644 group15/1521_653895972/src/task3/download/FileDownloader.java create mode 100644 group15/1521_653895972/src/task3/download/api/Connection.java create mode 100644 group15/1521_653895972/src/task3/download/api/ConnectionException.java create mode 100644 group15/1521_653895972/src/task3/download/api/ConnectionManager.java create mode 100644 group15/1521_653895972/src/task3/download/api/DownloadListener.java create mode 100644 group15/1521_653895972/src/task3/download/impl/ConnectionImpl.java create mode 100644 group15/1521_653895972/src/task3/download/impl/ConnectionManagerImpl.java create mode 100644 group15/1521_653895972/src/task3/test/FileDownloaderTest.java create mode 100644 group15/1521_653895972/src/task3/test/WLinkedListTest.java delete mode 100644 group16/1012075117/DataStructure219/.classpath delete mode 100644 group16/1012075117/DataStructure219/.project delete mode 100644 group16/1012075117/DataStructure219/.settings/org.eclipse.jdt.core.prefs create mode 100644 group16/1012075117/src/com/coderising/download/DownloadThread.java create mode 100644 group16/1012075117/src/com/coderising/download/FileDownloader.java create mode 100644 group16/1012075117/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group16/1012075117/src/com/coderising/download/api/Connection.java create mode 100644 group16/1012075117/src/com/coderising/download/api/ConnectionException.java create mode 100644 group16/1012075117/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group16/1012075117/src/com/coderising/download/api/DownloadListener.java create mode 100644 group16/1012075117/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group16/1012075117/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group16/1012075117/src/com/coderising/litestruts/LoginAction.java create mode 100644 group16/1012075117/src/com/coderising/litestruts/Struts.java create mode 100644 group16/1012075117/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group16/1012075117/src/com/coderising/litestruts/View.java rename group16/1012075117/{DataStructure219/src/com/stackwei/DataStructure => src/com/coding/basic}/ArrayList.java (94%) create mode 100644 group16/1012075117/src/com/coding/basic/Iterator.java rename group16/1012075117/{DataStructure219/src/com/stackwei/DataStructure => src/com/coding/basic}/LinkedList.java (96%) create mode 100644 group16/1012075117/src/com/coding/basic/List.java rename group16/1012075117/{DataStructure219/src/com/stackwei/DataStructure => src/com/coding/basic}/Queue.java (85%) rename group16/1012075117/{DataStructure219/src/com/stackwei/DataStructure => src/com/coding/basic}/Stack.java (85%) create mode 100644 group16/1012075117/src/com/coding/basic/array/ArrayUtil.java create mode 100644 group16/1012075117/src/com/coding/basic/array/ArrayUtilTest.java create mode 100644 group16/1012075117/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group16/1012075117/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group16/1012075117/src/com/coding/basic/linklist/LinkedList.java create mode 100644 group16/2562124714/src/Test/StrutsTest.java create mode 100644 group16/2562124714/src/com/coderising/action/LoginAction.java create mode 100644 group16/2562124714/src/com/coderising/array/ArrayUtil.java create mode 100644 group16/2562124714/src/com/coderising/download/DownloadThread.java create mode 100644 group16/2562124714/src/com/coderising/download/FileDownloader.java create mode 100644 group16/2562124714/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group16/2562124714/src/com/coderising/download/api/Connection.java create mode 100644 group16/2562124714/src/com/coderising/download/api/ConnectionException.java create mode 100644 group16/2562124714/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group16/2562124714/src/com/coderising/download/api/DownloadListener.java create mode 100644 group16/2562124714/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group16/2562124714/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group16/2562124714/src/com/coderising/litestruts/Struts.java create mode 100644 group16/2562124714/src/com/coderising/litestruts/View.java create mode 100644 group16/2816977791/thirdExercise/src/DownloadThread.java create mode 100644 group16/2816977791/thirdExercise/src/FileDownloader.java create mode 100644 group16/2816977791/thirdExercise/src/FileDownloaderTest.java rename {group24/798277403/src/week3 => group16/2816977791/thirdExercise/src}/api/Connection.java (95%) create mode 100644 group16/2816977791/thirdExercise/src/api/ConnectionException.java create mode 100644 group16/2816977791/thirdExercise/src/api/ConnectionManager.java create mode 100644 group16/2816977791/thirdExercise/src/api/DownloadListener.java create mode 100644 group16/2816977791/thirdExercise/src/basic/Iterator.java create mode 100644 group16/2816977791/thirdExercise/src/basic/LinkedList.java create mode 100644 group16/2816977791/thirdExercise/src/basic/LinkedListTest.java create mode 100644 group16/2816977791/thirdExercise/src/basic/List.java create mode 100644 group16/2816977791/thirdExercise/src/impl/ConnectionImpl.java create mode 100644 group16/2816977791/thirdExercise/src/impl/ConnectionManagerImpl.java create mode 100644 group16/313001956/src/com/coderising/array/ArrayUtil.java create mode 100644 group16/313001956/src/com/coderising/download/DownloadThread.java create mode 100644 group16/313001956/src/com/coderising/download/FileDownloader.java create mode 100644 group16/313001956/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group16/313001956/src/com/coderising/download/api/Connection.java create mode 100644 group16/313001956/src/com/coderising/download/api/ConnectionException.java create mode 100644 group16/313001956/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group16/313001956/src/com/coderising/download/api/DownloadListener.java create mode 100644 group16/313001956/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group16/313001956/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group16/313001956/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group16/313001956/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group16/313001956/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group16/313001956/src/com/coderising/litestruts/LoginAction.java create mode 100644 group16/313001956/src/com/coderising/litestruts/Struts.java create mode 100644 group16/313001956/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group16/313001956/src/com/coderising/litestruts/View.java create mode 100644 group16/313001956/src/com/coding/basic/LinkedListTest.java create mode 100644 group16/313001956/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group16/313001956/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group16/420355244/Homework3/src/com/coderising/array/ArrayUtil.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/DownloadThread.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/FileDownloader.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/api/Connection.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/api/ConnectionException.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/api/DownloadListener.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group16/420355244/Homework3/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group16/420355244/Homework3/src/com/coderising/litestruts/LoginAction.java create mode 100644 group16/420355244/Homework3/src/com/coderising/litestruts/Struts.java create mode 100644 group16/420355244/Homework3/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group16/420355244/Homework3/src/com/coderising/litestruts/View.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/ArrayList.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/BinaryTreeNode.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/Iterator.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/LinkedList.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/List.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/Queue.java create mode 100644 group16/420355244/Homework3/src/com/coding/basic/Stack.java create mode 100644 group16/502059278/src/cn/mark/work0312/MutiDownload.java create mode 100644 group17/1158154002/src/test03/Iterator.java create mode 100644 group17/1158154002/src/test03/LinkedList.java rename {group15/1513_121469918/HomeWork01/src/coding => group17/1158154002/src/test03}/List.java (91%) create mode 100644 group17/1158154002/src/test03/MyTest.java delete mode 100644 group17/1204187480/code/homework/basic/src/test/java/com/coding/api/ArrayListTest.java rename group17/1264835468/src/{assignment2_26 => assignment0226}/ArrayUtil.java (95%) rename group17/1264835468/src/{assignment2_26 => assignment0226}/ArrayUtilTest.java (95%) create mode 100644 group17/1264835468/src/assignment0226/LoginAction.java rename group17/1264835468/src/{assignment2_26 => assignment0226}/Struts.java (96%) create mode 100644 group17/1264835468/src/assignment0226/StrutsTest.java create mode 100644 group17/1264835468/src/assignment0226/View.java rename group17/1264835468/src/{assignment2_26 => assignment0226}/XmlParser.java (95%) create mode 100644 group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java create mode 100644 group17/1264835468/src/assignment0326/jvm/test/ClassFileLoaderTest.java create mode 100644 group17/1264835468/src/assignment0326/jvm/test/EmployeeV1.java create mode 100644 group17/1264835468/src/assignment0326/lru/Clock.java create mode 100644 group17/1264835468/src/assignment0326/lru/LRUPageFrame.java create mode 100644 group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java create mode 100644 group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group17/1282579502/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group17/1282579502/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LinkedList.java create mode 100644 group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group17/240094626/work_jvm_1/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group17/785396327/3.12/link/LinkedList.java create mode 100644 group17/785396327/3.12/link/LinkedListTest.java create mode 100644 group17/785396327/3.26/jvm_1/ClassFileLoader.java rename {group24/798277403/src/week4/test => group17/785396327/3.26/jvm_1}/ClassFileloaderTest.java (75%) create mode 100644 group17/785396327/3.26/jvm_1/EmployeeV1.java create mode 100644 group17/785396327/3.26/lru/LRUPageFrame.java create mode 100644 group17/785396327/3.26/lru/LRUPageFrameTest.java create mode 100644 group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java create mode 100644 group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java create mode 100644 group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java create mode 100644 group17/article/20170326-20170402.md create mode 100644 group17/article/20170402-20170409.md create mode 100644 group17/count/reward.md create mode 100644 group22/1158477486/src/TestCollection/ArrayUtil.java create mode 100644 group22/1158477486/src/TestCollection/Struts.java create mode 100644 group22/1158477486/src/TestCollection/StrutsTest.java create mode 100644 group22/1158477486/src/TestCollection/View.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/DownloadThread.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloader.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/FileDownloaderTest.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/Connection.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionException.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/ConnectionManager.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/api/DownloadListener.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionImpl.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/impl/ConnectionManagerImpl.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/Iterator.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedList.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/LinkedListTest.java create mode 100644 group22/1193590951/githubitem/src/com/github/mrwengq/tid/list/List.java create mode 100644 group22/1258890344/src/com/coderising/download/DownloadThread.java create mode 100644 group22/1258890344/src/com/coderising/download/FileDownloader.java create mode 100644 group22/1258890344/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group22/1258890344/src/com/coderising/download/api/Connection.java create mode 100644 group22/1258890344/src/com/coderising/download/api/ConnectionException.java create mode 100644 group22/1258890344/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group22/1258890344/src/com/coderising/download/api/DownloadListener.java create mode 100644 group22/1258890344/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group22/1258890344/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/DownloadThread.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloader.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/FileDownloaderTest.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/api/Connection.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionException.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/api/ConnectionManager.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/api/DownloadListener.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group22/1335499238/coding2017/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group22/17457741/src/thirdwork/DownloadThread.java create mode 100644 group22/17457741/src/thirdwork/FileDownloader.java create mode 100644 group22/17457741/src/thirdwork/api/Connection.java create mode 100644 group22/17457741/src/thirdwork/api/ConnectionException.java create mode 100644 group22/17457741/src/thirdwork/api/ConnectionManager.java create mode 100644 group22/17457741/src/thirdwork/api/DownloadListener.java create mode 100644 group22/17457741/src/thirdwork/impl/ConnectionImpl.java create mode 100644 group22/17457741/src/thirdwork/impl/ConnectionManagerImpl.java create mode 100644 group22/2622819383/Task2/ArrayUtil.java create mode 100644 group22/2622819383/Task2/litestruts/LoginAction.java create mode 100644 group22/2622819383/Task2/litestruts/Struts.java create mode 100644 group22/2622819383/Task2/litestruts/StrutsTest.java rename {group24/798277403/src/week2 => group22/2622819383/Task2}/litestruts/View.java (93%) create mode 100644 group22/2622819383/Task3/LinkedList.java create mode 100644 group22/2622819383/Task3/download/Connection.java create mode 100644 group22/2622819383/Task3/download/DownloadThread.java create mode 100644 group22/2622819383/Task3/download/FileDownloader.java rename "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" => "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" (100%) create mode 100644 group22/910725683/week02/array/src/com/coderising/array/ArrayUtil.java create mode 100644 group22/910725683/week02/array/test/com/coderising/array/ArrayUtilTest.java create mode 100644 group22/910725683/week02/litestruts/src/com/coderising/litestruts/LoginAction.java create mode 100644 group22/910725683/week02/litestruts/src/com/coderising/litestruts/Struts.java create mode 100644 group22/910725683/week02/litestruts/src/com/coderising/litestruts/View.java create mode 100644 group22/910725683/week02/litestruts/test/com/coderising/litestruts/StrutsTest.java create mode 100644 group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java rename group24/1148285693/learning2017/{mini-jvm/src/main/java/me/lzb => common/src/main/java/me/lzb/common}/utils/FileUtils.java (83%) rename group24/1148285693/learning2017/{mini-jvm/src/main/java/me/lzb => common/src/main/java/me/lzb/common}/utils/StringUtils.java (79%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/ArrayList.java (98%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/ArrayUtil.java (99%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/BinaryTreeNode.java (97%) create mode 100644 group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/Iterator.java (80%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{algorithm => basic}/LRUPageFrame.java (99%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/LinkedList.java (99%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/List.java (86%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/Queue.java (94%) rename group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/{datastructure => basic}/Stack.java (97%) create mode 100644 group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java rename group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/{datastructure => basic}/ArrayListTest.java (96%) create mode 100644 group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java rename group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/{algorithm => basic}/LRUPageFrameTest.java (95%) rename group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/{datastructure => basic}/LinkedListTest.java (98%) create mode 100644 group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java delete mode 100644 group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java create mode 100644 group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java rename group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/{loader => jvm}/EmployeeV1.java (95%) create mode 100644 group24/1148285693/learning2017/other/src/main/java/me/lzb/other/graph/Graph.java create mode 100644 group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java create mode 100644 group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java create mode 100644 group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java create mode 100644 group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java create mode 100644 group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java create mode 100644 group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java rename group24/121111914/src/com/github/ipk2015/coding2017/basic/{ => stack}/Stack.java (63%) create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/StackUtil.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExprTest.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/test/StackUtilTest.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/AttributeInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LineNumberTable.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableItem.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableTable.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/StackMapTable.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/AccessFlag.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassIndex.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/field/Field.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ByteCodeIterator.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader1.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileParser.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/util/Util.java create mode 100644 group24/1525619747/homework_20170402/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group24/1525619747/homework_20170402/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group24/1525619747/homework_20170402/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group24/1525619747/homework_20170402/src/com/coderising/lru/LRUPageFrame.java create mode 100644 group24/1525619747/homework_20170402/src/com/coderising/lru/test/LRUPageFrameTest.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrame.java create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrameTest.java rename group24/315863321/src/main/java/com/johnChnia/coding2017/basic/{ => linklist}/LinkedList.java (98%) rename group24/315863321/src/main/java/com/johnChnia/coding2017/basic/{ => stack}/Stack.java (94%) create mode 100644 group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/StackUtil.java create mode 100644 group24/315863321/src/test/java/com/johnChnia/coding2017/basic/stack/StackUtilTest.java create mode 100644 group24/448641125/src/com/donaldy/basic/StackUtil.java create mode 100644 group24/448641125/src/com/donaldy/basic/expr/InfixExpr.java create mode 100644 group24/448641125/src/com/donaldy/basic/expr/InfixExprTest.java create mode 100644 group24/448641125/src/com/donaldy/jvm/attr/AttributeInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/attr/CodeAttr.java create mode 100644 group24/448641125/src/com/donaldy/jvm/attr/LineNumberTable.java create mode 100644 group24/448641125/src/com/donaldy/jvm/attr/LocalVariableItem.java create mode 100644 group24/448641125/src/com/donaldy/jvm/attr/LocalVariableTable.java create mode 100644 group24/448641125/src/com/donaldy/jvm/attr/StackMapTable.java create mode 100644 group24/448641125/src/com/donaldy/jvm/clz/AccessFlag.java create mode 100644 group24/448641125/src/com/donaldy/jvm/clz/ClassFile.java create mode 100644 group24/448641125/src/com/donaldy/jvm/clz/ClassIndex.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/ClassInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/ConstantInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/ConstantPool.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/FieldRefInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/MethodRefInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/NameAndTypeInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/NullConstantInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/StringInfo.java create mode 100644 group24/448641125/src/com/donaldy/jvm/constant/UTF8Info.java create mode 100644 group24/448641125/src/com/donaldy/jvm/field/Field.java create mode 100644 group24/448641125/src/com/donaldy/jvm/loader/ByteCodeIterator.java create mode 100644 group24/448641125/src/com/donaldy/jvm/loader/ClassFileParser.java create mode 100644 group24/448641125/src/com/donaldy/jvm/method/Method.java create mode 100644 group24/448641125/src/com/donaldy/jvm/util/Util.java create mode 100644 group24/448641125/src/com/donaldy/test/StackUtilTest.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/AccessFlag.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassFile.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassIndex.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ClassInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantPool.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/FieldRefInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/MethodRefInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NullConstantInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/StringInfo.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/UTF8Info.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileParser.java create mode 100644 group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/util/Util.java create mode 100644 group24/494800949/src/main/java/com/coding/week5/stack/StackUtil.java create mode 100644 group24/494800949/src/test/java/com/coding/week5/stack/StackUtilTest.java create mode 100644 group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java create mode 100644 group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java create mode 100644 group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java create mode 100644 group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java delete mode 100644 group24/798277403/out/production/zhouliang/week2/litestruts/struts.xml rename group24/798277403/src/{week1 => basic}/ArrayList.java (99%) rename group24/798277403/src/{week1 => basic}/ArrayListTest.java (98%) rename group24/798277403/src/{week1 => basic}/BinaryTree.java (99%) rename group24/798277403/src/{week1 => basic}/BinaryTreeNode.java (99%) rename group24/798277403/src/{week1 => basic}/Iterator.java (90%) rename group24/798277403/src/{week4 => basic}/LRU/LRUPageFrame.java (99%) rename group24/798277403/src/{week4 => basic}/LRU/LRUPageFrameTest.java (98%) rename group24/798277403/src/{week4 => basic}/LRU/MyLRUPageFrame.java (99%) rename group24/798277403/src/{week1 => basic}/LinkedList.java (98%) rename group24/798277403/src/{week1 => basic}/LinkedListTest.java (98%) rename group24/798277403/src/{week1 => basic}/List.java (93%) rename group24/798277403/src/{week1 => basic}/Queue.java (97%) rename group24/798277403/src/{week1 => basic}/QueueTest.java (97%) rename group24/798277403/src/{week1 => basic}/Stack.java (97%) rename group24/798277403/src/{week1 => basic}/StackTest.java (97%) rename group24/798277403/src/{week2 => basic}/array/ArrayUtil.java (99%) rename group24/798277403/src/{week2 => basic}/array/ArrayUtilTest.java (99%) rename group24/798277403/src/{week3 => basic}/linkedlist/LinkedList.java (99%) rename group24/798277403/src/{week3 => basic}/linkedlist/LinkedListTest.java (95%) rename group24/798277403/src/{week3 => basic}/linkedlist/List.java (89%) create mode 100644 group24/798277403/src/basic/stack/StackUtil.java create mode 100644 group24/798277403/src/basic/stack/StackUtilTest.java rename group24/798277403/src/{week3 => download}/DownloadThread.java (83%) rename group24/798277403/src/{week3 => download}/FileDownloader.java (96%) create mode 100644 group24/798277403/src/download/api/Connection.java rename group24/798277403/src/{week3 => download}/api/ConnectionException.java (85%) create mode 100644 group24/798277403/src/download/api/ConnectionManager.java create mode 100644 group24/798277403/src/download/api/DownloadListener.java rename group24/798277403/src/{week3 => download}/impl/ConnectionImpl.java (91%) rename {group01/895457260/code => group24/798277403}/src/download/impl/ConnectionManagerImpl.java (99%) rename group24/798277403/src/{week3 => download}/test/ConnectionTest.java (88%) rename group24/798277403/src/{week3 => download}/test/FileDownloaderTest.java (86%) rename group24/798277403/src/{week2 => }/litestruts/LoginAction.java (97%) rename group24/798277403/src/{week2 => }/litestruts/Struts.java (98%) create mode 100644 group24/798277403/src/litestruts/StrutsTest.java create mode 100644 group24/798277403/src/litestruts/View.java create mode 100644 group24/798277403/src/mini_jvm/clz/AccessFlag.java create mode 100644 group24/798277403/src/mini_jvm/clz/ClassFile.java create mode 100644 group24/798277403/src/mini_jvm/clz/ClassIndex.java create mode 100644 group24/798277403/src/mini_jvm/constant/ClassInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/ConstantInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/ConstantPool.java create mode 100644 group24/798277403/src/mini_jvm/constant/FieldRefInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/MethodRefInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/NameAndTypeInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/NullConstantInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/StringInfo.java create mode 100644 group24/798277403/src/mini_jvm/constant/UTF8Info.java create mode 100644 group24/798277403/src/mini_jvm/loader/ByteCodeIterator.java create mode 100644 group24/798277403/src/mini_jvm/loader/ClassFileLoader.java create mode 100644 group24/798277403/src/mini_jvm/loader/ClassFileParser.java create mode 100644 group24/798277403/src/mini_jvm/test/ClassFileloaderTest.java create mode 100644 group24/798277403/src/mini_jvm/test/EmployeeV1.java create mode 100644 group24/798277403/src/mini_jvm/util/Util.java delete mode 100644 group24/798277403/src/week2/litestruts/struts.xml delete mode 100644 group24/798277403/src/week4/loader/ClassFileLoader.java create mode 100644 group24/815591664/2017Learning/src/com/coderising/array/ArrayUtil.java create mode 100644 group24/815591664/2017Learning/src/com/coderising/litestruts/LoginAction.java create mode 100644 group24/815591664/2017Learning/src/com/coderising/litestruts/Struts.java create mode 100644 group24/815591664/2017Learning/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group24/815591664/2017Learning/src/com/coderising/litestruts/View.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/ArrayList.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/BinaryTree.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/BinaryTreeNode.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/Iterator.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/LinkedList.java rename {group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm => group24/815591664/2017Learning/src/com/coding/basic}/List.java (64%) create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/Queue.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/Stack.java create mode 100644 group24/815591664/2017Learning/src/com/coding/basic/TestArrayList.java create mode 100644 group26/1515345281/src/Collection/blog create mode 100644 group26/1515345281/src/week2/blog create mode 100644 group26/1515345281/src/week2/struts2/Configuration.java create mode 100644 group26/1515345281/src/week2/struts2/ConfigurationException.java create mode 100644 group26/1515345281/src/week2/struts2/ReflectionUtil.java create mode 100644 group26/1515345281/src/week2/struts2/test/ConfigurationTest.java create mode 100644 group26/1515345281/src/week2/struts2/test/ReflectionTest.java create mode 100644 group26/1515345281/src/week3/blog create mode 100644 group26/1515345281/src/week3/download/DownloadThread.java create mode 100644 group26/1515345281/src/week3/download/FileDownloader.java rename {group01/895457260/code/src => group26/1515345281/src/week3}/download/api/Connection.java (93%) create mode 100644 group26/1515345281/src/week3/download/api/ConnectionException.java rename {group01/895457260/code/src => group26/1515345281/src/week3}/download/api/ConnectionManager.java (84%) create mode 100644 group26/1515345281/src/week3/download/api/DownloadListener.java create mode 100644 group26/1515345281/src/week3/download/api/impl/ConnectionImpl.java create mode 100644 group26/1515345281/src/week3/download/api/impl/ConnectionManagerImpl.java create mode 100644 group26/1515345281/src/week3/download/test/ConnectionTest.java create mode 100644 group26/1515345281/src/week3/download/test/FileDownloaderTest.java create mode 100644 group26/1515345281/src/week3/list/Iterator.java create mode 100644 group26/1515345281/src/week3/list/LinkedList.java create mode 100644 group26/1515345281/src/week3/list/LinkedListTest.java create mode 100644 group26/1515345281/src/week3/list/List.java create mode 100644 group26/1515345281/src/week3/list/ListUtils.java create mode 100644 group26/1515345281/src/week4/origin/jvm/loader/ClassFileLoader.java create mode 100644 group26/1515345281/src/week4/origin/jvm/loader/LRUPageFrame.java create mode 100644 group26/1515345281/src/week4/origin/jvm/loader/blog create mode 100644 group26/1515345281/src/week4/origin/jvm/loader/test/ClassFileLoaderTest.java create mode 100644 group26/1515345281/src/week4/origin/jvm/loader/test/EmployeeV1.java create mode 100644 group26/1515345281/src/week4/origin/jvm/loader/test/LRUPageFrameTest.java create mode 100644 group26/1778842360/third homework/LinkedList/LinkedList.java create mode 100644 group26/1778842360/third homework/LinkedList/LinkedListTest.java create mode 100644 group26/1778842360/third homework/TTD/ConfigurationTest.java create mode 100644 group26/1778842360/third homework/TTD/Configureation.java create mode 100644 group26/1778842360/third homework/TTD/LoginAction.java create mode 100644 group26/1778842360/third homework/TTD/ReflectionUtil.java create mode 100644 group26/1778842360/third homework/TTD/ReflectionUtilTest.java create mode 100644 group26/1778842360/third homework/TTD/Struts.java create mode 100644 group26/1778842360/third homework/TTD/View.java create mode 100644 group26/191191717/src/week3/com/coding/download/DownloadThread.java create mode 100644 group26/191191717/src/week3/com/coding/download/FileDownloader.java create mode 100644 group26/191191717/src/week3/com/coding/download/FileDownloaderTest.java create mode 100644 group26/191191717/src/week3/com/coding/download/api/Connection.java create mode 100644 group26/191191717/src/week3/com/coding/download/api/ConnectionException.java create mode 100644 group26/191191717/src/week3/com/coding/download/api/ConnectionManager.java create mode 100644 group26/191191717/src/week3/com/coding/download/api/DownloadListener.java create mode 100644 group26/191191717/src/week3/com/coding/download/impl/ConnectionImpl.java create mode 100644 group26/191191717/src/week3/com/coding/download/impl/ConnectionManagerImpl.java create mode 100644 group26/2441547139/week1/collection/MyArrayList.java create mode 100644 group26/2441547139/week1/collection/MyLinkedList.java create mode 100644 group26/2441547139/week1/collection/MyQueue.java create mode 100644 group26/2441547139/week1/collection/MyStack.java create mode 100644 group26/2441547139/week2/arrayutil/ArrayUtils.java create mode 100644 group26/2441547139/week2/struts/LoginAction.java create mode 100644 group26/2441547139/week2/struts/LoginOutAction.java create mode 100644 group26/2441547139/week2/struts/Struts.java create mode 100644 group26/2441547139/week2/struts/View.java create mode 100644 group26/2441547139/week3/linkedlist/MyLinkedLists.java create mode 100644 group26/2441547139/week3/thread/DownloadThread.java create mode 100644 group26/2441547139/week3/thread/FileDownload.java create mode 100644 group26/2441547139/week3/thread/ThreadDownload.java create mode 100644 "group26/2441547139/\346\234\211\351\201\223\347\254\224\350\256\260.txt" create mode 100644 group26/723161901/jvm/loader/ClassFileLoader.java create mode 100644 group26/723161901/jvm/test/ClassFileloaderTest.java create mode 100644 group26/723161901/jvm/test/EmployeeV1.java create mode 100644 group26/723161901/src/com/download/download/DownloadThread.java create mode 100644 group26/723161901/src/com/download/download/FileDownloader.java create mode 100644 group26/723161901/src/com/download/download/FileDownloaderTest.java create mode 100644 group26/723161901/src/com/download/download/api/Connection.java create mode 100644 group26/723161901/src/com/download/download/api/ConnectionException.java create mode 100644 group26/723161901/src/com/download/download/api/ConnectionManager.java create mode 100644 group26/723161901/src/com/download/download/api/DownloadListener.java create mode 100644 group26/723161901/src/com/download/download/impl/ConnectionImpl.java create mode 100644 group26/723161901/src/com/download/download/impl/ConnectionManagerImpl.java create mode 100644 group26/723161901/src/com/litestruts/LoginAction.java create mode 100644 group26/723161901/src/com/litestruts/Struts.java create mode 100644 group26/723161901/src/com/litestruts/StrutsTest.java create mode 100644 group26/723161901/src/com/litestruts/StrutsXmlReader.java create mode 100644 group26/723161901/src/com/litestruts/View.java create mode 100644 group26/723161901/src/com/litestruts/strutsBean/Action.java create mode 100644 group26/89460886/src/week03/source/download/DownloadThread.java create mode 100644 group26/89460886/src/week03/source/download/FileDownloader.java create mode 100644 group26/89460886/src/week03/source/download/api/Connection.java create mode 100644 group26/89460886/src/week03/source/download/api/ConnectionException.java create mode 100644 group26/89460886/src/week03/source/download/api/ConnectionManager.java create mode 100644 group26/89460886/src/week03/source/download/api/DownloadListener.java create mode 100644 group26/89460886/src/week03/source/download/impl/ConnectionImpl.java create mode 100644 group26/89460886/src/week03/source/download/impl/ConnectionManagerImpl.java create mode 100644 group26/89460886/src/week03/source/linkedlist/SinglyLinkedList.java create mode 100644 group26/89460886/src/week03/test/TestDownload.java create mode 100644 group26/89460886/src/week03/test/TestSinglyLinkedList.java create mode 100644 group26/89460886/src/week04/source/LRUPageFrame.java create mode 100644 group26/89460886/src/week04/test/TestLRUPageFrame.java create mode 100644 group26/lizhy2017/homework/second/array/ArrayUtilTest.java create mode 100644 group26/lizhy2017/homework/third/basic/LRUPageFameTest.java create mode 100644 group26/lizhy2017/homework/third/basic/LRUPageFrame.java create mode 100644 group26/lizhy2017/homework/third/basic/LinkedList.java create mode 100644 group26/lizhy2017/homework/third/download/DownloadThread.java create mode 100644 group26/lizhy2017/homework/third/download/FileDownloader.java create mode 100644 group26/lizhy2017/homework/third/download/FileDownloaderTest.java create mode 100644 group26/lizhy2017/homework/third/download/api/Connection.java create mode 100644 group26/lizhy2017/homework/third/download/api/ConnectionException.java create mode 100644 group26/lizhy2017/homework/third/download/api/ConnectionManager.java create mode 100644 group26/lizhy2017/homework/third/download/api/DownloadListener.java create mode 100644 group26/lizhy2017/homework/third/download/impl/ConnectionImpl.java create mode 100644 group26/lizhy2017/homework/third/download/impl/ConnectionManagerImpl.java create mode 100644 group26/lizhy2017/homework/third/download/utils/HttpUtil.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/DownloadThread.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/FileDownloader.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/api/Connection.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/api/ConnectionException.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/api/DownloadListener.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/test/ConnectionTest.java create mode 100644 group27/1016908591/week03/src/com/coderising/download/test/FileDownloaderTest.java create mode 100644 group27/1016908591/week03/src/com/coding/basic/LinkedList.java create mode 100644 group27/1016908591/week04/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group27/1016908591/week04/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group27/1016908591/week04/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group27/1016908591/week04/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group27/1016908591/week04/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/DownloadThread.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloader.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/FileDownloaderTest.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/api/Connection.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionException.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/api/ConnectionManager.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/api/DownloadListener.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group27/1252327158/task3_20170326/download/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 "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" create mode 100644 group27/383117348/src/com/coderising/download/DownloadThread.java create mode 100644 group27/383117348/src/com/coderising/download/FileDownloader.java create mode 100644 group27/383117348/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group27/383117348/src/com/coderising/download/api/Connection.java create mode 100644 group27/383117348/src/com/coderising/download/api/ConnectionException.java create mode 100644 group27/383117348/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group27/383117348/src/com/coderising/download/api/DownloadListener.java create mode 100644 group27/383117348/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group27/383117348/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group27/383117348/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group27/383117348/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group27/383117348/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group27/383117348/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group27/383117348/src/com/coding/basic/linklist/LRUPageFrameTest.java rename group27/383117348/src/com/coding/basic/{ => linklist}/LinkedList.java (61%) create mode 100644 group27/513274874/data-structure/down.jpg create mode 100644 group27/513274874/data-structure/src/com/coderising/download/DownloadThread.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/FileDownloader.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/api/Connection.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/api/ConnectionException.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/api/DownloadListener.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/demo/DownThread.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/demo/MutilDown.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group27/513274874/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group27/513274874/data-structure/src/com/coderising/litestruts/LoginAction.java create mode 100644 group27/513274874/data-structure/src/com/coderising/litestruts/Struts.java create mode 100644 group27/513274874/data-structure/src/com/coderising/litestruts/StrutsTest.java create mode 100644 group27/513274874/data-structure/src/com/coderising/litestruts/View.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/ArrayList.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/BinaryTreeNode.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/Iterator.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/List.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/Queue.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/Stack.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtil.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtilTest.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java create mode 100644 group27/513274874/data-structure/src/com/coding/basic/linklist/LinkedList.java create mode 100644 group27/513274874/data-structure/test/com/coding/basic/ArrayListTest.java create mode 100644 group27/513274874/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group27/513274874/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group27/513274874/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/DownloadThread.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/FileDownloader.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/FileDownloaderTest.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/Test.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/api/Connection.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionException.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/api/DownloadListener.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group27/815591664/2017Learning/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 liuxin/data-structure/src/com/coding/basic/stack/Stack.java create mode 100644 liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java create mode 100644 liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java create mode 100644 liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java create mode 100644 liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/clz/AccessFlag.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassIndex.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/ClassInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/ConstantPool.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/FieldRefInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/MethodRefInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/NullConstantInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/StringInfo.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/constant/UTF8Info.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/field/Field.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java create mode 100644 liuxin/mini-jvm/src/com/coderising/jvm/util/Util.java diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/ArrayList.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructure/ArrayList.java deleted file mode 100644 index 23ed3f6bc2..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/ArrayList.java +++ /dev/null @@ -1,75 +0,0 @@ -package week01.BasicDataStructure; - -import java.util.Arrays; - -public class ArrayList implements List { - - private int size = 0; - - private Object[] elementData = new Object[100]; - - public void add(Object o){ - ensureCapacity(size + 1); //size increase,in order to have enough capacity. - elementData[size++] = o; //similar to: elementData[size]=o; size++; - } - - private void ensureCapacity(int minCapacity){ - if(minCapacity > elementData.length){ - grow(minCapacity); - } - } - - private void grow(int minCapacity){ - int oldCapacity = elementData.length; - int newCapacity = oldCapacity + ( oldCapacity >> 1 ); - if(newCapacity < minCapacity){ - newCapacity = minCapacity; - } - elementData = Arrays.copyOf(elementData, newCapacity); - - } - - public void add(int index, Object o){ - if(index < 0 || index > size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); - ensureCapacity(size+1); - System.arraycopy(elementData, index, elementData, index + 1, size - index); - elementData[index] = o; - size++; - } - - public Object get(int index){ - if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); - return elementData[index]; - } - - public Object remove(int index){ - if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); - Object data_index = elementData[index]; - System.arraycopy(elementData, index + 1, elementData, index, size - index - 1); - elementData[size - 1] = null; - size--; - return data_index; - } - - public int size(){ - return size; - } - - public Iterator iterator(){ - return new ArrayListIterator(); - } - - private class ArrayListIterator implements Iterator{ - - private int pos = 0; - - public boolean hasNext() { - return pos < size; - } - - public Object next() { - return elementData[pos++]; - } - } - -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/BinaryTreeNode.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructure/BinaryTreeNode.java deleted file mode 100644 index a4fb2cf8b9..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/BinaryTreeNode.java +++ /dev/null @@ -1,56 +0,0 @@ -package week01.BasicDataStructure; - -public class BinaryTreeNode{ - - private Object data; - private BinaryTreeNode left; - private BinaryTreeNode right; - - public BinaryTreeNode(Object data){ - this.data = data; - left = null; - right = null; - } - - 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((Integer)o < (Integer)this.data) - { - if(this.left == null){ - BinaryTreeNode node = new BinaryTreeNode(o); - this.setLeft(node); - return node; - }else{ - return this.left.insert(o); - } - }else{ - if(this.right == null){ - BinaryTreeNode node = new BinaryTreeNode(o); - this.setRight(node); - return node; - }else{ - return this.right.insert(o); - } - } - } - } - - diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/LinkedList.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructure/LinkedList.java deleted file mode 100644 index 35b1158cd1..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/LinkedList.java +++ /dev/null @@ -1,113 +0,0 @@ -package week01.BasicDataStructure; - -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){ - if(index < 0 || index >size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size); - 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++; - } - - public Object get(int index){ - if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size); - Node pos = head; - for(int i = 0;i < index;i++){ - pos = pos.next; - } - return pos.data; - } - - public Object remove(int index){ - if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size); - 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; - } - - 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; - } - } -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Queue.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Queue.java deleted file mode 100644 index e0ab6bbb9c..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Queue.java +++ /dev/null @@ -1,25 +0,0 @@ -package week01.BasicDataStructure; - -public class Queue { - - private LinkedList linkedList = new LinkedList(); - private int size = 0; - - public void enQueue(Object o){ - linkedList.add(o); - size++; - } - - public Object deQueue(){ - size--; - return linkedList.removeFirst(); - } - - public boolean isEmpty(){ - return linkedList.size() == 0; - } - - public int size(){ - return size; - } -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Stack.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Stack.java deleted file mode 100644 index 53f99b37c7..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Stack.java +++ /dev/null @@ -1,25 +0,0 @@ -package week01.BasicDataStructure; - -public class Stack { - private ArrayList elementData = new ArrayList(); - private int size = 0; - - public void push(Object o){ - elementData.add(o); - size++; - } - - public Object pop(){ - return elementData.remove(--size); - } - - public Object peek(){ - return elementData.get(size - 1); - } - public boolean isEmpty(){ - return elementData.size() == 0; - } - public int size(){ - return elementData.size(); - } -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/AllTest.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/AllTest.java deleted file mode 100644 index 5d5f07d815..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/AllTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package week01.BasicDataStructureTest; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - ArrayListTest.class, - BinaryTreeNodeTest.class, - LinkedListTest.class, - QueueTest.class, - StackTest.class -}) - -public class AllTest { - -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/ArrayListTest.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/ArrayListTest.java deleted file mode 100644 index c5513acfda..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/ArrayListTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package week01.BasicDataStructureTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import week01.BasicDataStructure.ArrayList; -import week01.BasicDataStructure.Iterator; - -public class ArrayListTest { - - private ArrayList arrayList = new ArrayList(); - - @Before - public void setUp() throws Exception { - for(int i = 0;i < 100 ; i++){ - arrayList.add(i); - } - } - - @Test - public void testAddObject() { - for(int i = 0;i < 100;i++){ - Assert.assertEquals(arrayList.get(i), i); - } - } - - @Test - public void testAddIntObject() { - arrayList.add(0,10); - arrayList.add(22, 44); - arrayList.add(40, 5); - arrayList.add(100,88); - Assert.assertEquals(arrayList.get(0), 10); - Assert.assertEquals(arrayList.get(22),44); - Assert.assertEquals(arrayList.get(40), 5); - Assert.assertEquals(arrayList.get(100), 88); - } - - @Test - public void testGet() { - Assert.assertEquals(arrayList.get(0), 0); - Assert.assertEquals(arrayList.get(33), 33); - Assert.assertEquals(arrayList.get(77), 77); - Assert.assertEquals(arrayList.get(99), 99); - } - - @Test - public void testRemove() { - Assert.assertEquals(arrayList.remove(0), 0); - Assert.assertEquals(arrayList.remove(0), 1); - Assert.assertEquals(arrayList.remove(97), 99); - Assert.assertEquals(arrayList.size(), 97); - } - - @Test - public void testSize() { - Assert.assertEquals(arrayList.size(), 100); - arrayList.add(5,5); - Assert.assertEquals(arrayList.size(),101); - arrayList.remove(5); - Assert.assertEquals(arrayList.size(), 100); - } - - @Test - public void testIterator() { - Iterator iterator = arrayList.iterator(); - for(int i=0;iterator.hasNext();i++){ - Assert.assertEquals(iterator.next(),i); - } - } -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/BinaryTreeNodeTest.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/BinaryTreeNodeTest.java deleted file mode 100644 index 724e6c0e03..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/BinaryTreeNodeTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package week01.BasicDataStructureTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import week01.BasicDataStructure.BinaryTreeNode; - - -public class BinaryTreeNodeTest { - - private BinaryTreeNode root = new BinaryTreeNode(5); - - @Before - public void setUp() throws Exception { - root.insert(2); - root.insert(7); - root.insert(1); - root.insert(6); - } - - @Test - public void testGetData() { - Assert.assertEquals(root.getData(), 5); - Assert.assertEquals(root.getLeft().getData(), 2); - Assert.assertEquals(root.getRight().getData(), 7); - Assert.assertEquals(root.getLeft().getLeft().getData(), 1); - Assert.assertEquals(root.getRight().getLeft().getData(), 6); - } - - @Test - public void testSetData() { - root.setData(8); - Assert.assertEquals(root.getData(),8); - root.getLeft().setData(88); - Assert.assertEquals(root.getLeft().getData(),88); - root.getRight().setData(888); - Assert.assertEquals(root.getRight().getData(),888); - } - - @Test - public void testGetLeft() { - BinaryTreeNode node_left = root.getLeft(); - Assert.assertEquals(node_left.getData(), 2); - BinaryTreeNode node_left_left = root.getLeft().getLeft(); - Assert.assertEquals(node_left_left.getData(), 1); - } - - @Test - public void testSetLeft() { - BinaryTreeNode node = new BinaryTreeNode(100); - root.setLeft(node); - Assert.assertEquals(root.getLeft().getData(), 100); - } - - @Test - public void testGetRight() { - BinaryTreeNode node_right = root.getRight(); - Assert.assertEquals(node_right.getData(), 7); - root.insert(8); - BinaryTreeNode node_right_right = root.getRight().getRight(); - Assert.assertEquals(node_right_right.getData(), 8); - } - - @Test - public void testSetRight() { - BinaryTreeNode node = new BinaryTreeNode(100); - root.setRight(node); - Assert.assertEquals(root.getRight().getData(), 100); - } - - @Test - public void testInsert() { - root.insert(4); - root.insert(8); - Assert.assertEquals(root.getLeft().getRight().getData(), 4); - Assert.assertEquals(root.getRight().getRight().getData(), 8); - } - -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/LinkedListTest.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/LinkedListTest.java deleted file mode 100644 index 2fb20d12f4..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/LinkedListTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package week01.BasicDataStructureTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import week01.BasicDataStructure.Iterator; -import week01.BasicDataStructure.LinkedList; - -public class LinkedListTest { - - private LinkedList linkedList = new LinkedList(); - - @Before - public void setUp() throws Exception { - for(int i=0;i<100;i++){ - linkedList.add(i); - } - } - - @Test - public void testAddObject() { - for(int i=0;i<200;i++){ - linkedList.add(i); - } - for(int i=0;i<100;i++){ - Assert.assertEquals(linkedList.get(i), i); - } - for(int i=100;i<300;i++){ - Assert.assertEquals(linkedList.get(i), i-100); - } - } - - @Test - public void testAddIntObject() { - linkedList.add(0, 10); - Assert.assertEquals(linkedList.get(0), 10); - linkedList.add(5,60); - Assert.assertEquals(linkedList.get(5), 60); - Assert.assertEquals(linkedList.get(101), 99); - } - - @Test - public void testGet() { - for(int i =0;i<100;i++){ - Assert.assertEquals(linkedList.get(i), i); - } - } - - @Test - public void testRemove() { - Assert.assertEquals(linkedList.remove(0), 0); - Assert.assertEquals(linkedList.remove(0), 1); - Assert.assertEquals(linkedList.size(), 98); - linkedList.remove(97); - Assert.assertEquals(linkedList.get(96), 98); - } - - @Test - public void testSize() { - linkedList.add(0); - Assert.assertEquals(linkedList.size(), 101); - linkedList.add(0, 10); - Assert.assertEquals(linkedList.size(), 102); - linkedList.remove(0); - Assert.assertEquals(linkedList.size(), 101); - } - - @Test - public void testAddFirst() { - linkedList.addFirst(22); - Assert.assertEquals(linkedList.get(0), 22); - linkedList.addFirst(44); - Assert.assertEquals(linkedList.get(0), 44); - Assert.assertEquals(linkedList.size(), 102); - } - - @Test - public void testAddLast() { - linkedList.addLast(22); - Assert.assertEquals(linkedList.get(100), 22); - linkedList.addLast(44); - Assert.assertEquals(linkedList.get(101), 44); - } - - @Test - public void testRemoveFirst() { - Assert.assertEquals(linkedList.removeFirst(), 0); - Assert.assertEquals(linkedList.removeFirst(), 1); - } - - @Test - public void testRemoveLast() { - Assert.assertEquals(linkedList.removeLast(),99 ); - Assert.assertEquals(linkedList.removeLast(), 98); - } - - @Test - public void testIterator() { - Iterator iterator = linkedList.iterator(); - for(int i = 0;iterator.hasNext();i++){ - Assert.assertEquals(iterator.next(), i); - } - } - -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/QueueTest.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/QueueTest.java deleted file mode 100644 index 7302b5ec38..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/QueueTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package week01.BasicDataStructureTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import week01.BasicDataStructure.Queue; - - -public class QueueTest { - - Queue queue = new Queue(); - - @Before - public void setUp() throws Exception { - for(int i=0;i<100;i++){ - queue.enQueue(i); - } - } - - @Test - public void testEnQueue() { - Assert.assertEquals(queue.size(), 100); - for(int i =0;i<100;i++){ - queue.enQueue(i); - } - Assert.assertEquals(queue.size(), 200); - } - - @Test - public void testDeQueue() { - for(int i =0;i<100;i++){ - Assert.assertEquals(queue.deQueue(), i); - } - - } - - @Test - public void testIsEmpty() { - Assert.assertEquals(queue.isEmpty(), false); - for(int i=0;i<100;i++){ - queue.deQueue(); - } - Assert.assertEquals(queue.isEmpty(), true); - } - - @Test - public void testSize() { - Assert.assertEquals(queue.size(), 100); - queue.enQueue(100); - Assert.assertEquals(queue.size(), 101); - queue.deQueue(); - Assert.assertEquals(queue.size(), 100); - } - -} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/StackTest.java b/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/StackTest.java deleted file mode 100644 index ae6d3a39d4..0000000000 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructureTest/StackTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package week01.BasicDataStructureTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import week01.BasicDataStructure.Stack; - - -public class StackTest { - - Stack stack = new Stack(); - - @Before - public void setUp() throws Exception { - for(int i =0 ;i <100;i++){ - stack.push(i); - } - } - - @Test - public void testPush() { - Assert.assertEquals(stack.peek(), 99); - for(int i =0;i <200;i++){ - stack.push(i); - } - Assert.assertEquals(stack.peek(), 199); - Assert.assertEquals(stack.size(), 300); - } - - @Test - public void testPop() { - Assert.assertEquals(stack.pop(), 99); - Assert.assertEquals(stack.pop(), 98); - for(int i=0;i<98;i++){ - stack.pop(); - } - Assert.assertEquals(stack.size(), 0); - } - - @Test - public void testPeek() { - for(int i=0;i<100;i++){ - Assert.assertEquals(stack.peek(), 99); - Assert.assertEquals(stack.size(), 100); - } - stack.pop(); - Assert.assertEquals(stack.peek(), 98); - Assert.assertEquals(stack.peek(), 98); - } - - @Test - public void testIsEmpty() { - Assert.assertEquals(stack.isEmpty(), false); - for(int i =0 ;i <100;i++){ - stack.pop(); - } - Assert.assertEquals(stack.isEmpty(), true); - } - - @Test - public void testSize() { - stack.push(100); - Assert.assertEquals(stack.size(), 101); - stack.pop(); - Assert.assertEquals(stack.size(), 100); - stack.peek(); - Assert.assertEquals(stack.size(), 100); - } - -} diff --git a/group01/1814014897/zhouhui/src/week04/jvm/loader/ClassFileLoader.java b/group01/1814014897/zhouhui/src/week04/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..7b4d99d013 --- /dev/null +++ b/group01/1814014897/zhouhui/src/week04/jvm/loader/ClassFileLoader.java @@ -0,0 +1,52 @@ + +package week04.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws Exception { + URL base = this.getClass().getResource("/"); + String baseToString = ""+base; + String filePath = baseToString.replaceAll("file:/", "")+className.replace(".", "\\")+".class"; + //String filePath = clzPaths.get(0)+"\\"+className.replace(".", "\\")+".class"; //符合Junit测试调用addClassPath方法 + File file = new File(filePath); + + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + int len = 0; + while((len = bis.read(buffer)) != -1){ + baos.write(buffer,0,len); + } + return baos.toByteArray(); + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + StringBuffer strBuffer = new StringBuffer(); + for(int i=0;i 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/378213871/.classpath b/group01/378213871/.classpath index d815a5f517..695129670d 100644 --- a/group01/378213871/.classpath +++ b/group01/378213871/.classpath @@ -3,6 +3,6 @@ - + diff --git a/group01/378213871/src/com/coderising/week03/basic/LinkedList.java b/group01/378213871/src/com/coderising/week03/basic/LinkedList.java new file mode 100644 index 0000000000..7602a2f11e --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/basic/LinkedList.java @@ -0,0 +1,390 @@ +package com.coderising.week03.basic; + +import java.util.NoSuchElementException; +import java.util.Stack; + +import com.coding.basic.week01.Iterator; +import com.coding.basic.week01.List; + +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; + } + } + public Iterator iterator(){ + return null; + } + + + 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); + } + + 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(); + } + + /** + * 假设当前链表和参数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 = (int)this.get(i1); + int value2 = (int)list.get(i2); + + if(value1 == value2) { + result.add(value1); + i1++; + i2++; + } else if (value1 < value2) { + i1++; + } else { + i2++; + } + } + return result; + } +} diff --git a/group01/378213871/src/com/coderising/week03/basic/LinkedListEx.java b/group01/378213871/src/com/coderising/week03/basic/LinkedListEx.java new file mode 100644 index 0000000000..f203d68b4c --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/basic/LinkedListEx.java @@ -0,0 +1,250 @@ +package com.coderising.week03.basic; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import com.coding.basic.week01.List; + + +public class LinkedListEx implements List { + + + + private Node head; + + private int size; + + public void add(Object o){ + if (head == null) { + head = new Node(o); + size++; + } else{ + addLast(o); + } + } + public void add(int index , Object o){ + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException(); + } + if (index == 0) { + addFirst(o); + } else { + //定义标记节点sentinelNode,标记节点的下一个节点即为要新加的元素 + Node sentinelNode = head; + for (int i = 0; i < index - 1; i++) { + sentinelNode = sentinelNode.next; + } + Node node = new Node(o); + node.next = sentinelNode.next; + sentinelNode.next = node; + size++; + } + } + public Object get(int index){ + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } else { + Node indexNode = head; + for (int i = 0; i < index; i++) { + indexNode = indexNode.next; + } + return indexNode.data; + } + } + public Object remove(int index){ + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException(); + } else { + /** + * sentinelNode是所删除节点的上一个节点; + * indexNode是需要被删除的节点 + */ + Node sentinelNode = head; + Node indexNode = head; + for (int i = 0; i < index - 1; i++) { + sentinelNode = sentinelNode.next; + } + for (int i = 0; i < index; i++) { + indexNode = indexNode.next; + } + Node nextIndexNode = indexNode.next; + sentinelNode.next = nextIndexNode; + indexNode.next = null; + size--; + return indexNode.data; + } + } + + 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){ + //定义尾节点并通过while循环找到当前链表的尾节点 + Node tailNode = head; + while (tailNode.next != null) { + tailNode = tailNode.next; + } + Node node = new Node(o); + tailNode.next = node; + size++; + } + public Object removeFirst(){ + if (head == null) { + throw new NoSuchElementException(); + } + Node newNode = head; + head = head.next; + size--; + return newNode.data; + } + 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; + } + + public Iterator iterator(){ + return null; + } + + + private static class Node{ + Object data; + Node next; // 下一个节点 + + private Node(Object data) { + this.data = data; + next = null; + } + } + + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + //节点逆置后的下一个节点;原头节点变尾节点所以初始为null + Node reverseNode = null; + while (head != null) { + Node temp = head; //临时节点temp存放旧头节点 + head = head.next; //旧头节点的下一个节点变为新头节点 + temp.next = reverseNode; //将reverseNode赋给旧头节点的下一个节点 + reverseNode = temp; //将temp(旧头节点)赋给reverseNode + } + head = reverseNode; + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + int startIndex = size/2; + for(int i = 0; i < startIndex; i++) { + head = head.next; + size--; + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if (i < 0) { + throw new IllegalArgumentException(); + } + //要考虑到超出size的情况 + if (i + length >= size) { + length = size - i; + } + if (i == 0) { + for (int j = 0; j < length; j++) { + head = head.next; + } + size = size - length; + } else { + Node startNode = head; //startNode的下一个节点指向第i个元素 + for (int j = 0; j < i - 1; j++) { + startNode = startNode.next; + } + Node endNode = startNode; + for (int j = 0; j < length; j++) { + endNode = endNode.next; + } + startNode.next = endNode.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 static int[] getElements(LinkedListEx list){ + return null; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedListEx list){ + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedListEx intersection( LinkedListEx list){ + return null; + } +} diff --git a/group01/378213871/src/com/coderising/week03/basic/LinkedListTest.java b/group01/378213871/src/com/coderising/week03/basic/LinkedListTest.java new file mode 100644 index 0000000000..e0793e0ef1 --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/basic/LinkedListTest.java @@ -0,0 +1,202 @@ +package com.coderising.week03.basic; + +import org.junit.Assert; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.week03.basic.LinkedList; + + +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 testGetElement() { + 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/group01/378213871/src/com/coderising/week03/download/DownloadThread.java b/group01/378213871/src/com/coderising/week03/download/DownloadThread.java new file mode 100644 index 0000000000..845e570798 --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/DownloadThread.java @@ -0,0 +1,48 @@ +package com.coderising.week03.download; + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.week03.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(){ + + 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/group01/378213871/src/com/coderising/week03/download/FileDownloader.java b/group01/378213871/src/com/coderising/week03/download/FileDownloader.java new file mode 100644 index 0000000000..f5a8e0d903 --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/FileDownloader.java @@ -0,0 +1,129 @@ +package com.coderising.week03.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.week03.download.api.Connection; +import com.coderising.week03.download.api.ConnectionException; +import com.coderising.week03.download.api.ConnectionManager; +import com.coderising.week03.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 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 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(); + } + + 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; + } + + 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/378213871/src/com/coderising/week03/download/FileDownloaderTest.java b/group01/378213871/src/com/coderising/week03/download/FileDownloaderTest.java new file mode 100644 index 0000000000..9f56ec3e92 --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.coderising.week03.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.week03.download.api.ConnectionManager; +import com.coderising.week03.download.api.DownloadListener; +import com.coderising.week03.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://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + + FileDownloader downloader = new FileDownloader(url,"/Users/Victor/desktop/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/group01/378213871/src/com/coderising/week03/download/api/Connection.java b/group01/378213871/src/com/coderising/week03/download/api/Connection.java new file mode 100644 index 0000000000..a00b340d6b --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.week03.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/group01/378213871/src/com/coderising/week03/download/api/ConnectionException.java b/group01/378213871/src/com/coderising/week03/download/api/ConnectionException.java new file mode 100644 index 0000000000..a51703e6df --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/api/ConnectionException.java @@ -0,0 +1,8 @@ +package com.coderising.week03.download.api; + +public class ConnectionException extends Exception { + public ConnectionException(Exception e) { + super(e); + } + +} diff --git a/group01/378213871/src/com/coderising/week03/download/api/ConnectionManager.java b/group01/378213871/src/com/coderising/week03/download/api/ConnectionManager.java new file mode 100644 index 0000000000..561993f33b --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.week03.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-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/DownloadListener.java b/group01/378213871/src/com/coderising/week03/download/api/DownloadListener.java similarity index 60% rename from group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/DownloadListener.java rename to group01/378213871/src/com/coderising/week03/download/api/DownloadListener.java index a2dc179298..02db08f642 100644 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/api/DownloadListener.java +++ b/group01/378213871/src/com/coderising/week03/download/api/DownloadListener.java @@ -1,4 +1,4 @@ -package com.github.eulerlcs.jmr.multiDL.api; +package com.coderising.week03.download.api; public interface DownloadListener { public void notifyFinished(); diff --git a/group01/378213871/src/com/coderising/week03/download/impl/ConnectionImpl.java b/group01/378213871/src/com/coderising/week03/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..159f368ab2 --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/impl/ConnectionImpl.java @@ -0,0 +1,82 @@ +package com.coderising.week03.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.week03.download.api.Connection; +import com.coderising.week03.download.api.ConnectionException; + +class ConnectionImpl implements Connection{ + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException { + try { + url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); + + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream is = httpConn.getInputStream(); + + byte[] buff = new byte[BUFFER_SIZE]; + + int totalLen = endPos -startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + while(baos.size() < totalLen) { + + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff,0, len); + } + + if (baos.size() > totalLen) { + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + + URLConnection con; + try { + con = url.openConnection(); + + return con.getContentLength(); + + } catch (IOException e) { + e.printStackTrace(); + } + + return -1; + } + + @Override + public void close() { + + + } + +} diff --git a/group01/378213871/src/com/coderising/week03/download/impl/ConnectionManagerImpl.java b/group01/378213871/src/com/coderising/week03/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..38e3028e5b --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.week03.download.impl; + +import com.coderising.week03.download.api.Connection; +import com.coderising.week03.download.api.ConnectionException; +import com.coderising.week03.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return new ConnectionImpl(url); + } + +} diff --git a/group01/378213871/src/com/coderising/week03/download/test/ConnectionTest.java b/group01/378213871/src/com/coderising/week03/download/test/ConnectionTest.java new file mode 100644 index 0000000000..8a42668358 --- /dev/null +++ b/group01/378213871/src/com/coderising/week03/download/test/ConnectionTest.java @@ -0,0 +1,53 @@ +package com.coderising.week03.download.test; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.week03.download.api.Connection; +import com.coderising.week03.download.api.ConnectionManager; +import com.coderising.week03.download.impl.ConnectionManagerImpl; + +import junit.framework.Assert; + +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/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java b/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..4490da73ab --- /dev/null +++ b/group01/765324639/src/zavier/week04/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,72 @@ +package zavier.week04.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.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws ClassNotFoundException { + File classFile = getClassFile(className); + return readFileToByteArray(classFile); + } + + private File getClassFile(String className) throws ClassNotFoundException { + File classFile = null; + String classFilePath = convertClassNameToFilePath(className); + for (String path : clzPaths) { + File file = new File(path, classFilePath); + if (file.exists()) { + classFile = file; + break; + } + } + + if (classFile == null) { // 文件不存在 + throw new ClassNotFoundException(); + } + return classFile; + } + + private byte[] readFileToByteArray(File classFile) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (InputStream in = new FileInputStream(classFile);) { + byte[] data = new byte[1024]; + int len = -1; + while ((len = in.read(data)) != -1) { + out.write(data, 0, len); + } + } catch (FileNotFoundException e) { // 调用此函数时,已经确定文件是存在的 + e.printStackTrace(); + } catch (IOException e1) { + e1.printStackTrace(); + } + return out.toByteArray(); + } + + private String convertClassNameToFilePath(String fillClassName) { + return fillClassName.replace(".", "\\") + ".class"; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath() { + return String.join(";", clzPaths); + } + + + +} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java b/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..72c4c24127 --- /dev/null +++ b/group01/765324639/src/zavier/week04/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,90 @@ +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(); + } + +} diff --git a/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java b/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..28e4981fbe --- /dev/null +++ b/group01/765324639/src/zavier/week04/coderising/jvm/test/EmployeeV1.java @@ -0,0 +1,31 @@ +package zavier.week04.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(); + + } +} diff --git a/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java b/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..46a61f19aa --- /dev/null +++ b/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrame.java @@ -0,0 +1,177 @@ +package zavier.week04.coderising.linklist; + +/** + * 用双向链表实现LRU算法 + * + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + } + + private int capacity; + private int size; + + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + if (isEmpty()) { + initFirstNode(pageNum); + return; + } + + if (contains(pageNum)) { + moveToFirst(pageNum); + } else { + insert(pageNum); + } + } + + private void initFirstNode(int pageNum) { + Node node = new Node(pageNum); + first = last = node; + size++; + } + + private void moveToFirst(int pageNum) { + if (isFirst(pageNum)) { + return; + } + if (isLast(pageNum)) { + moveLastToFirst(); + } else { + moveMidToFirst(pageNum); + } + } + + private void moveLastToFirst() { + Node temp = last; + + removeLast(); + + addToFirst(temp); + } + + private void addToFirst(Node temp) { + temp.next = first; + first.prev = temp; + first = temp; + size++; + } + + private void moveMidToFirst(int pageNum) { + Node node = removeMidNode(pageNum); + addToFirst(node); + } + + private Node removeMidNode(int pageNum) { + Node temp = getNode(pageNum); + temp.prev.next = temp.next; + temp.next.prev = temp.prev; + + temp.next = null; + temp.prev = null; + + size--; + + return temp; + } + + private void insert(int pageNum) { + if (isFill()) { + removeLast(); + } + insertToFirst(pageNum); + } + + private void removeLast() { + last = last.prev; + last.next = null; + size--; + } + + private void insertToFirst(int pageNum) { + Node node = new Node(pageNum); + + addToFirst(node); + } + + private boolean contains(int pageNum) { + return indexOf(pageNum) != -1; + } + + private int indexOf(int num) { + Node temp = first; + for (int i = 0; i < size; i++) { + if (temp.pageNum == num) { + return i; + } + temp = temp.next; + } + return -1; + } + + private Node getNode(int pageNum) { + Node temp; + temp = first; + for (int i = 0; i < size; i++) { + if (temp.pageNum == pageNum) { + break; + } + temp = temp.next; + } + return temp; + } + + private boolean isEmpty() { + return size == 0; + } + + private boolean isFirst(int pageNum) { + return first.pageNum == pageNum; + } + + private boolean isLast(int pageNum) { + return last.pageNum == pageNum; + } + + private boolean isFill() { + return size == 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/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java b/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..d022f48144 --- /dev/null +++ b/group01/765324639/src/zavier/week04/coderising/linklist/LRUPageFrameTest.java @@ -0,0 +1,30 @@ +package zavier.week04.coderising.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/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/litestruts/struts.xml b/group01/895457260/code/src/litestruts/struts.xml deleted file mode 100644 index aad7e3f7fc..0000000000 --- a/group01/895457260/code/src/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file 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/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/932573198/20170306/src/com/coderising/download/DownloadThread.java b/group01/932573198/20170306/src/com/coderising/download/DownloadThread.java index 8101fec04d..07894e6a1f 100644 --- a/group01/932573198/20170306/src/com/coderising/download/DownloadThread.java +++ b/group01/932573198/20170306/src/com/coderising/download/DownloadThread.java @@ -1,32 +1,43 @@ package com.coderising.download; +import java.io.File; import java.io.IOException; +import java.io.RandomAccessFile; import com.coderising.download.api.Connection; +import com.coderising.download.api.DownloadListener; public class DownloadThread extends Thread { Connection conn; int startPos; int endPos; - byte[] content; - - public DownloadThread(Connection conn, int startPos, int endPos) { + String targetPath; + DownloadListener listener; + public DownloadThread(){} + + public DownloadThread(Connection conn, int startPos, int endPos, String targetPath, DownloadListener listener) { this.conn = conn; this.startPos = startPos; this.endPos = endPos; + this.targetPath = targetPath; + this.listener = listener; } public void run() { + System.out.println("下载:" + startPos + "--" + endPos); try { - content = conn.read(startPos, endPos); + byte[] content = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile(new File(this.targetPath), "rw"); + //偏移量超出文件末尾时会自动更改其长度 + raf.seek(startPos); + raf.write(content, 0, content.length); + raf.close(); + listener.notifyFinished(); } catch (IOException e) { e.printStackTrace(); } - } - - public byte[] getContent() { - return content; + System.out.println("线程" + startPos + "-" + endPos + "的下载完成."); } } diff --git a/group01/932573198/20170306/src/com/coderising/download/FileDownloader.java b/group01/932573198/20170306/src/com/coderising/download/FileDownloader.java index 01e98c3711..fe9a8143fa 100644 --- a/group01/932573198/20170306/src/com/coderising/download/FileDownloader.java +++ b/group01/932573198/20170306/src/com/coderising/download/FileDownloader.java @@ -1,8 +1,5 @@ package com.coderising.download; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -10,23 +7,25 @@ import com.coderising.download.api.ConnectionException; import com.coderising.download.api.ConnectionManager; import com.coderising.download.api.DownloadListener; -/** - * 借鉴954958168 - */ + public class FileDownloader { + String targetPath; + String url; DownloadListener listener; ConnectionManager cm; - public FileDownloader(String _url) { - this.url = _url; + final int threadCount = 3; + public FileDownloader(String _url, String _targetPath) { + this.url = _url; + this.targetPath = _targetPath; } - public void execute() throws ConnectionException, InterruptedException, IOException { + public void execute() { // 在这里实现你的代码, 注意: 需要用多线程实现下载 // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, @@ -42,31 +41,26 @@ public void execute() throws ConnectionException, InterruptedException, IOExcept // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 - - Connection conn = cm.open(this.url); - int length = conn.getContentLength(); - conn.close(); - List threads = new ArrayList<>(); - int i; - for (i = 0; i < 3; i++) { - DownloadThread thread = new DownloadThread(cm.open(this.url), i * (length / 3), (i + 1) * (length / 3) - 1); - threads.add(thread); - thread.start(); + Connection conn = null; + try { + conn = cm.open(this.url); + } catch (ConnectionException e) { + e.printStackTrace(); } - if (i * (length / 3) < length) { - DownloadThread thread = new DownloadThread(cm.open(this.url), i * (length / 3), length - 1); - threads.add(thread); - thread.start(); + int length = conn.getContentLength(); + + List list = new ArrayList<>(); + int n = length / threadCount; + list.add(-1); + for (int i = 1; i < threadCount; i++) { + list.add(i * n - 1); } - for (DownloadThread thread : threads) { - thread.join(); + if (length / threadCount != 0) { + list.add(length - 1); } - FileOutputStream fos = new FileOutputStream(new File("temp.jpg")); - for (DownloadThread thread : threads) { - fos.write(thread.getContent()); + for (int i = 1; i < list.size(); i++) { + new DownloadThread(conn, list.get(i - 1) + 1, list.get(i), this.targetPath, this.listener).start(); } - fos.close(); - this.listener.notifyFinished(); } @@ -78,8 +72,4 @@ public void setConnectionManager(ConnectionManager ucm) { this.cm = ucm; } - public DownloadListener getListener() { - return this.listener; - } - } diff --git a/group01/932573198/20170306/src/com/coderising/download/FileDownloaderTest.java b/group01/932573198/20170306/src/com/coderising/download/FileDownloaderTest.java index 5434dbfa10..6f5a012b55 100644 --- a/group01/932573198/20170306/src/com/coderising/download/FileDownloaderTest.java +++ b/group01/932573198/20170306/src/com/coderising/download/FileDownloaderTest.java @@ -1,12 +1,9 @@ package com.coderising.download; -import java.io.IOException; - import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.coderising.download.api.ConnectionException; import com.coderising.download.api.ConnectionManager; import com.coderising.download.api.DownloadListener; import com.coderising.download.impl.ConnectionManagerImpl; @@ -24,8 +21,10 @@ public void tearDown() throws Exception { @Test public void testDownload() { + String url = "http://localhost:8080/test/kittens.jpg"; - FileDownloader downloader = new FileDownloader(url); + String targetPath = "E://kittens.jpg"; + FileDownloader downloader = new FileDownloader(url, targetPath); ConnectionManager cm = new ConnectionManagerImpl(); downloader.setConnectionManager(cm); downloader.setListener(new DownloadListener() { @@ -34,11 +33,8 @@ public void notifyFinished() { downloadFinished = true; } }); - try { - downloader.execute(); - } catch (ConnectionException | InterruptedException | IOException e1) { - e1.printStackTrace(); - } + + downloader.execute(); // 等待多线程下载程序执行完毕 while (!downloadFinished) { @@ -51,7 +47,6 @@ public void notifyFinished() { } } System.out.println("下载完成!"); - } } diff --git a/group01/932573198/20170306/src/com/coderising/download/api/ConnectionException.java b/group01/932573198/20170306/src/com/coderising/download/api/ConnectionException.java index 0a52074ed1..c3ed7396e7 100644 --- a/group01/932573198/20170306/src/com/coderising/download/api/ConnectionException.java +++ b/group01/932573198/20170306/src/com/coderising/download/api/ConnectionException.java @@ -1,15 +1,5 @@ package com.coderising.download.api; -public class ConnectionException extends RuntimeException { - public ConnectionException(String message) { - super(message); - } - - public ConnectionException(String message, Throwable cause) { - super(message, cause); - } - - public ConnectionException(Throwable cause) { - super(cause); - } +public class ConnectionException extends Exception { + } diff --git a/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionImpl.java b/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionImpl.java index eb75b3c25f..a937084949 100644 --- a/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionImpl.java +++ b/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionImpl.java @@ -1,42 +1,61 @@ package com.coderising.download.impl; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; import com.coderising.download.api.Connection; public class ConnectionImpl implements Connection { - private FileInputStream fis; - private File file; + private HttpURLConnection ucon = null; - public ConnectionImpl(String source) throws FileNotFoundException { - file = new File(getClass().getClassLoader().getResource(source).getFile()); - fis = new FileInputStream(file); + private URL url = null; + + public ConnectionImpl() { + } + + public ConnectionImpl(String _url) throws MalformedURLException, IOException { + url = new URL(_url); } @Override public byte[] read(int startPos, int endPos) throws IOException { - fis.skip(startPos); + ucon = (HttpURLConnection) url.openConnection(); + // openConnection()已将连接打开 + // 不用ucon.connect(); + ucon.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream in = ucon.getInputStream(); + byte[] content = new byte[endPos - startPos + 1]; - fis.read(content, 0, content.length); + + byte[] data = new byte[1024]; + int read = 0, i = 0; + while ((read = in.read(data, 0, data.length)) != -1) { + System.arraycopy(data, 0, content, i, read); + i += read; + } return content; } @Override public int getContentLength() { - return (int) file.length(); - } - - @Override - public void close() { + int length = 0; try { - fis.close(); + ucon = (HttpURLConnection) url.openConnection(); + length = ucon.getContentLength(); } catch (IOException e) { e.printStackTrace(); + } finally { + ucon.disconnect(); } + return length; + } + + @Override + public void close() { } } diff --git a/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionManagerImpl.java index 851f1146a0..537155c67d 100644 --- a/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionManagerImpl.java +++ b/group01/932573198/20170306/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -1,19 +1,19 @@ package com.coderising.download.impl; -import java.io.FileNotFoundException; +import java.io.IOException; 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 = null; + @Override - public Connection open(String url) throws ConnectionException { - ConnectionImpl conn = null; + public Connection open(String url) { try { conn = new ConnectionImpl(url); - } catch (FileNotFoundException e) { + } catch (IOException e) { e.printStackTrace(); } return conn; 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 0eb7a002d8d65b343682b73c4f1c508a405e860e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20442 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 Z{y$fArVM(bw#EPe002ovPDHLkV1fvtqmlps 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..b9eb85129a --- /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..af9d7238e3 --- /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..6f5f006a59 --- /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..06ac2257bb --- /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/src/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml b/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml deleted file mode 100644 index 0d3fd6495f..0000000000 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ 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 95% 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 index 1c1b9a6df3..dd72d043fb 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/ArrayList.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/ArrayList.java @@ -1,78 +1,78 @@ -package com.github.miniyk2012.coding2017.basic; - -import java.util.Arrays; - - -public class ArrayList implements List { - - private int size = 0; - private int DEFAULT_LENGTH = 10; - - private Object[] elementData = new Object[DEFAULT_LENGTH]; - - public void add(Object o){ - ensureCapcacity(); - elementData[size++] = o; - } - public void add(int index, Object o){ - ensurnPosition(index); - ensureCapcacity(); - System.arraycopy(elementData, index, elementData, index + 1, - size - index); - elementData[index] = o; - size++; - } - - public Object get(int index){ - ensureIndex(index); - return elementData[index]; - } - - public Object remove(int index){ - ensureIndex(index); - Object temp = elementData[index]; - System.arraycopy(elementData, index+1, elementData, index, - size - index - 1); - elementData[size-1] = null; - size--; - return temp; - } - - public void clear() { - elementData = new Object[DEFAULT_LENGTH]; - size = 0; - } - - public int size(){ - return size; - } - - public Iterator iterator(){ - Iterator iterator = new IteratorImp(this); - return iterator; - } - - private void ensureCapcacity() { - int oldLength = elementData.length; - if (size+1 > oldLength) { - elementData = Arrays.copyOf(elementData, 2*oldLength); - } - } - - private void ensureIndex(int index) { - if (index >= size || index < 0) - throw new ArrayIndexOutOfBoundsException(String.format("index %d out of bounds [0-%d)", index, size)); - } - - private void ensurnPosition(int index) { - if (index <0 || index>size) - throw new ArrayIndexOutOfBoundsException(String.format("position %d out of position [0-%d)", index, size)); - } - - @Override - public String toString() { - Object[] tempArray = Arrays.copyOf(elementData, size); - return Arrays.toString(tempArray); - } - -} +package com.github.miniyk2012.coding2017.basic; + +import java.util.Arrays; + + +public class ArrayList implements List { + + private int size = 0; + private int DEFAULT_LENGTH = 10; + + private Object[] elementData = new Object[DEFAULT_LENGTH]; + + public void add(Object o){ + ensureCapcacity(); + elementData[size++] = o; + } + public void add(int index, Object o){ + ensurnPosition(index); + ensureCapcacity(); + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + elementData[index] = o; + size++; + } + + public Object get(int index){ + ensureIndex(index); + return elementData[index]; + } + + public Object remove(int index){ + ensureIndex(index); + Object temp = elementData[index]; + System.arraycopy(elementData, index+1, elementData, index, + size - index - 1); + elementData[size-1] = null; + size--; + return temp; + } + + public void clear() { + elementData = new Object[DEFAULT_LENGTH]; + size = 0; + } + + public int size(){ + return size; + } + + public Iterator iterator(){ + Iterator iterator = new IteratorImp(this); + return iterator; + } + + private void ensureCapcacity() { + int oldLength = elementData.length; + if (size+1 > oldLength) { + elementData = Arrays.copyOf(elementData, 2*oldLength); + } + } + + private void ensureIndex(int index) { + if (index >= size || index < 0) + throw new ArrayIndexOutOfBoundsException(String.format("index %d out of bounds [0-%d)", index, size)); + } + + private void ensurnPosition(int index) { + if (index <0 || index>size) + throw new ArrayIndexOutOfBoundsException(String.format("position %d out of position [0-%d)", index, size)); + } + + @Override + public String toString() { + Object[] tempArray = Arrays.copyOf(elementData, size); + return Arrays.toString(tempArray); + } + +} 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 95% 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 index 5b1f17342b..7c78767fb0 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/BinaryTreeNode.java @@ -1,55 +1,55 @@ -package com.github.miniyk2012.coding2017.basic; - -public class BinaryTreeNode > { - private E data; - private BinaryTreeNode left; - private BinaryTreeNode right; - - public BinaryTreeNode(E x) { - data = x; - } - public E getData() { - return data; - } - public void setData(E 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(E o){ - BinaryTreeNode node = new BinaryTreeNode(o); - boolean left = true; - BinaryTreeNode currentNode = this; - BinaryTreeNode previousNode = null; - - while (currentNode != null) { - previousNode = currentNode; - int compareTo = node.getData().compareTo(currentNode.getData()); - if (compareTo <= 0) { // 小于,往左插入 - currentNode = currentNode.left; - left = true; - } else { - currentNode = currentNode.right; - left = false; - } - } - if (left) { - previousNode.left = node; - } else { - previousNode.right = node; - } - return node; - } - -} +package com.github.miniyk2012.coding2017.basic; + +public class BinaryTreeNode > { + private E data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public BinaryTreeNode(E x) { + data = x; + } + public E getData() { + return data; + } + public void setData(E 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(E o){ + BinaryTreeNode node = new BinaryTreeNode(o); + boolean left = true; + BinaryTreeNode currentNode = this; + BinaryTreeNode previousNode = null; + + while (currentNode != null) { + previousNode = currentNode; + int compareTo = node.getData().compareTo(currentNode.getData()); + if (compareTo <= 0) { // 小于,往左插入 + currentNode = currentNode.left; + left = true; + } else { + currentNode = currentNode.right; + left = false; + } + } + if (left) { + previousNode.left = node; + } else { + previousNode.right = node; + } + return node; + } + +} 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 95% 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 index 7705715c84..589532f42d 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/Iterator.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Iterator.java @@ -1,6 +1,6 @@ -package com.github.miniyk2012.coding2017.basic; - -public interface Iterator { - boolean hasNext(); - Object next(); -} +package com.github.miniyk2012.coding2017.basic; + +public interface Iterator { + boolean hasNext(); + Object next(); +} 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 96% 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 index 0ba1d9861c..09e4e1b941 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/LinkedList.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/LinkedList.java @@ -1,365 +1,365 @@ -package com.github.miniyk2012.coding2017.basic; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.Objects; - -import org.omg.CORBA.PRIVATE_MEMBER; - -import com.sun.tracing.dtrace.ArgsAttributes; - -import utils.ArrayUtils; - -public class LinkedList implements List { - - private Node head; - private int size = 0; - - /** - * node接收的index一定是范围内的值,不可能越界 - * @param index - * @return a Node - */ - Node node(int index) { - Node x = head; - for (int i=0; i= size) - throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); - } - - private void checkPositionIndex(int index) { - if (index < 0 || index > size) - throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); - } - - /** - * 把该链表逆置 - * 例如链表为 3->7->10 , 逆置后变为 10->7->3 - */ - public void reverse(){ - // 自感写的还行,没有多余代码 - Node previous = null; - while (head != null) { - Node next = head.next; - head.next = previous; - previous = head; - head = next; - } - head = previous; - } - - /** - * 删除一个单链表的前半部分 - * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 - * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 - - */ - public void removeFirstHalf(){ - int halfIndex = size() / 2; - head = node(halfIndex); - size = size() - halfIndex; - } - - /** - * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 - * @param i - * @param length - * @throws Exception - */ - public void remove(int i, int length) throws Exception{ - if (length <0 || i <0 || i>=size()) throw new Exception(); - if (length == 0) return; - if (i+length>size()) throw new Exception(); - - Node after = (i+length==size()?null:node(i+length)); - if (i>=1) { - node(i-1).next = after; - } else { - head = after; - } - - size -= length; - } - - /** - * 假定当前链表和list均包含已升序排列的整数 - * 从当前链表中取出那些list所指定的元素 - * 例如当前链表 = 11->101->201->301->401->501->601->701 - * listB = 1->3->4->6 - * 返回的结果应该是[101,301,401,601] - * @param list - * @throws Exception - */ - public int[] getElements(LinkedList list) throws Exception { - // 不允许用get方法取得当前链表的元素,重分利用当前链表和list的有序性 - if (list.size == 0) return new int[0]; - if ((int)list.get(0)<0 || (int)list.get(list.size-1)>=size) { - throw new Exception(); - } - java.util.LinkedList aStandardList = new java.util.LinkedList<>(); - Node current = head; - for (int i=0,j=0; i bValue) { - b++; - } else if (aValue < bValue) { - a++; - } else { - cList.add(a); - a++; - b++; - } - } - return cList; - } - - public static LinkedList copy(LinkedList list) { - LinkedList copy = new LinkedList(); - Iterator it = list.iterator(); - while (it.hasNext()) { - copy.add(it.next()); - } - return copy; - } - - public static void main(String args[]) throws Exception { - LinkedList aLinkedList = new LinkedList(); - for (int i=0; i<4; i=i*i) { - aLinkedList.add(i); // [0,1,4,9] - } - LinkedList bLinkedList = new LinkedList(); - int[] z1 = aLinkedList.getElements(bLinkedList); // [] - System.out.println(Arrays.toString(z1)); - } -} +package com.github.miniyk2012.coding2017.basic; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Objects; + +import org.omg.CORBA.PRIVATE_MEMBER; + +import com.sun.tracing.dtrace.ArgsAttributes; + +import utils.ArrayUtils; + +public class LinkedList implements List { + + private Node head; + private int size = 0; + + /** + * node接收的index一定是范围内的值,不可能越界 + * @param index + * @return a Node + */ + Node node(int index) { + Node x = head; + for (int i=0; i= size) + throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); + } + + private void checkPositionIndex(int index) { + if (index < 0 || index > size) + throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + // 自感写的还行,没有多余代码 + Node previous = null; + while (head != null) { + Node next = head.next; + head.next = previous; + previous = head; + head = next; + } + head = previous; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int halfIndex = size() / 2; + head = node(halfIndex); + size = size() - halfIndex; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + * @throws Exception + */ + public void remove(int i, int length) throws Exception{ + if (length <0 || i <0 || i>=size()) throw new Exception(); + if (length == 0) return; + if (i+length>size()) throw new Exception(); + + Node after = (i+length==size()?null:node(i+length)); + if (i>=1) { + node(i-1).next = after; + } else { + head = after; + } + + size -= length; + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + * @throws Exception + */ + public int[] getElements(LinkedList list) throws Exception { + // 不允许用get方法取得当前链表的元素,重分利用当前链表和list的有序性 + if (list.size == 0) return new int[0]; + if ((int)list.get(0)<0 || (int)list.get(list.size-1)>=size) { + throw new Exception(); + } + java.util.LinkedList aStandardList = new java.util.LinkedList<>(); + Node current = head; + for (int i=0,j=0; i bValue) { + b++; + } else if (aValue < bValue) { + a++; + } else { + cList.add(a); + a++; + b++; + } + } + return cList; + } + + public static LinkedList copy(LinkedList list) { + LinkedList copy = new LinkedList(); + Iterator it = list.iterator(); + while (it.hasNext()) { + copy.add(it.next()); + } + return copy; + } + + public static void main(String args[]) throws Exception { + LinkedList aLinkedList = new LinkedList(); + for (int i=0; i<4; i=i*i) { + aLinkedList.add(i); // [0,1,4,9] + } + LinkedList bLinkedList = new LinkedList(); + int[] z1 = aLinkedList.getElements(bLinkedList); // [] + System.out.println(Arrays.toString(z1)); + } +} 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 95% 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 index c9eae11190..63db6ed431 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/List.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/List.java @@ -1,10 +1,10 @@ -package com.github.miniyk2012.coding2017.basic; - -public interface List { - void add(Object o); - void add(int index, Object o); - Object get(int index); - Object remove(int index); - int size(); - Iterator iterator(); -} +package com.github.miniyk2012.coding2017.basic; + +public interface List { + void add(Object o); + void add(int index, Object o); + Object get(int index); + Object remove(int index); + int size(); + Iterator iterator(); +} 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 94% 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 index bcb9d0f9e4..9f22f2471d 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/Queue.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Queue.java @@ -1,23 +1,23 @@ -package com.github.miniyk2012.coding2017.basic; - -public class Queue { - - // 队列入口 -》1,2,3,4 -》队列出口 - private LinkedList aList = new LinkedList(); - - public void enQueue(Object o){ - aList.addFirst(o); - } - - public Object deQueue(){ - return aList.removeLast(); - } - - public boolean isEmpty(){ - return aList.size() == 0; - } - - public int size(){ - return aList.size(); - } -} +package com.github.miniyk2012.coding2017.basic; + +public class Queue { + + // 队列入口 -》1,2,3,4 -》队列出口 + private LinkedList aList = new LinkedList(); + + public void enQueue(Object o){ + aList.addFirst(o); + } + + public Object deQueue(){ + return aList.removeLast(); + } + + public boolean isEmpty(){ + return aList.size() == 0; + } + + public int size(){ + return aList.size(); + } +} 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 94% 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 index ddfe76f774..b2f2d6366b 100644 --- a/group02/812350401/src/com/github/miniyk2012/coding2017/basic/Stack.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/Stack.java @@ -1,25 +1,25 @@ -package com.github.miniyk2012.coding2017.basic; - -public class Stack { - - // 栈顶 《-》 1,2,3,4 栈底 - private ArrayList elementData = new ArrayList(); - - public void push(Object o){ - elementData.add(0, o); - } - - public Object pop(){ - return elementData.remove(0); - } - - public Object peek(){ - return elementData.get(0); - } - public boolean isEmpty(){ - return elementData.size() == 0; - } - public int size(){ - return elementData.size(); - } -} +package com.github.miniyk2012.coding2017.basic; + +public class Stack { + + // 栈顶 《-》 1,2,3,4 栈底 + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + elementData.add(0, o); + } + + public Object pop(){ + return elementData.remove(0); + } + + public Object peek(){ + return elementData.get(0); + } + public boolean isEmpty(){ + return elementData.size() == 0; + } + public int size(){ + return elementData.size(); + } +} 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..05bd6716b1 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 @@ -1,279 +1,279 @@ -package com.github.miniyk2012.coding2017.coderising.array; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.IntStream; -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 size = origin.length; - if (size == 0) return; - int start = 0, end = size-1; - while (start < end) { - int temp = origin[start]; - origin[start++] = origin[end]; - origin[end--] = 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) return null; - List list=new ArrayList<>(); - for (int e : oldArray) { - if (e != 0) { - list.add(e); - } - } - return list2Array(list); - } - - /** - * 给定两个已经排序好的整形数组, 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) return null; - if (array1.length == 0) return Arrays.copyOf(array2, array2.length); - List list = array2List(array1); - int currentIndex = 0; - for (int e : array2) { - for (int index = currentIndex; index < list.size(); index++ ) { - currentIndex = index + 1; - if (list.get(index) == e) break; - if (list.get(index) > e) { - list.add(index, e); - break; - } - } - if (e > list.get(list.size()-1)) list.add(e); - } - return list2Array(list); - } - - /** - * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size - * 注意,老数组的元素在新数组中需要保持 - * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 - * [2,3,6,0,0,0] - * @param oldArray - * @param size - * @return - * @throws Exception - */ - public int[] grow(int [] oldArray, int size) throws Exception{ - if (oldArray==null) return null; - if (size < 0) throw new Exception(); - int oldSize = oldArray.length; - int[] newArray = new int[size+oldSize]; - System.arraycopy(oldArray, 0, newArray, 0, oldSize); - return newArray; - } - - /** - * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 - * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] - * max = 1, 则返回空数组 [] - * @param max - * @return - */ - public int[] fibonacci(int max){ - if (max <= 1) return new int[0]; - int i = 1, j = 1; - List list = new ArrayList<>(); - list.add(i); - list.add(j); - int next = i+j; - while (max > next) { - list.add(next); - i = j; - j = next; - next = i+j; - } - return list2Array(list); - } - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public int[] getPrimes(int max){ - // TODO 使用筛法,写的不好,有待改善 - if (max <= 2) return new int[0]; - List list = new ArrayList<>(); - int i; - for (i=2; i= 0) - list.remove(index); - k += currentNum; - } - currentNum = list.get(++i); - } - return list2Array(list); - } - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * @param max - * @return - */ - public int[] getPerfectNumbers(int max){ - List list = new ArrayList<>(); - int[] factors; - for (int i=1; i list = new ArrayList<>(); - for (int i=1; i < num; i++) { - if(num % i == 0) list.add(i); - } - return list2Array(list); - } - - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" - * @param array - * @param s - * @return - */ - public String join(int[] array, String seperator){ - if (array.length == 0) return ""; - if (array.length == 1) return "" + array[0]; - StringBuilder s = new StringBuilder(); - for (int i=0; i转换为相同顺序和长度的int[] - * @param list - * @return - */ - private int[] list2Array(List list) { - int size = list.size(); - int[] newArray = new int[size]; - for (int i=0; i - * @param array - * @return - */ - private List array2List(int[] array) { - List list = new ArrayList<>(); - for (int e : array) { - list.add(e); - } - return list; - } - - public static void main(String []args) throws Exception { - ArrayUtil arrayUtil = new ArrayUtil(); - - // merge - int[] a1 = {1,2,3}, a2 = {-4,-2,2,3,4}; -// int[] a1 = {}, a2 = {}; -// int[] a1 = {1,2,3}, a2 = {}; -// int[] a1 = {}, a2 = {1,2,3}; -// int[] a1 = {4,5,6}, a2 = {1,2,3}; - int[] a3 = arrayUtil.merge(a1, a2); - System.out.println(Arrays.toString(a3)); - - // reverse -// a1 = new int[] {}; -// a1 = new int[] {4,}; -// a1 = new int[] {4,3,5,6,7,7,8}; - a1 = new int[] {4,3,5,6,7,7,8, 9}; - arrayUtil.reverseArray(a1); - System.out.println(Arrays.toString(a1)); - - // remove zero -// a1 = new int[] {}; -// a1 = new int[] {0,0}; - a1 = new int[] {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; - a2 = arrayUtil.removeZero(a1); - System.out.println(Arrays.toString(a2)); - - // grow - a1 = new int[] {1,2,3}; - a2 = arrayUtil.grow(a1, 4); -// a2 = arrayUtil.grow(a1, 2); -// a2 = arrayUtil.grow(a1, 0); - System.out.println(Arrays.toString(a2)); - - // fibonacci - a1 = arrayUtil.fibonacci(15); -// a1 = arrayUtil.fibonacci(1); -// a1 = arrayUtil.fibonacci(2); -// a1 = arrayUtil.fibonacci(-2); - System.out.println(Arrays.toString(a1)); - - // prime - a1 = arrayUtil.getPrimes(2); -// a1 = arrayUtil.getPrimes(3); -// a1 = arrayUtil.getPrimes(8); -// a1 = arrayUtil.getPrimes(12); -// a1 = arrayUtil.getPrimes(23); -// a1 = arrayUtil.getPrimes(24); -// a1 = arrayUtil.getPrimes(50); - a1 = arrayUtil.getPrimes(100); - System.out.println(Arrays.toString(a1)); - - // perfectNumbers - a1 = arrayUtil.getPerfectNumbers(1000); - System.out.println(Arrays.toString(a1)); - - // join -// a1 = new int[] {}; -// a1 = new int[] {1}; - a1 = new int[] {1,2,3}; - String str = arrayUtil.join(a1, "-"); - System.out.println(str); - - } -} +package com.github.miniyk2012.coding2017.coderising.array; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; +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 size = origin.length; + if (size == 0) return; + int start = 0, end = size-1; + while (start < end) { + int temp = origin[start]; + origin[start++] = origin[end]; + origin[end--] = 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) return null; + List list=new ArrayList<>(); + for (int e : oldArray) { + if (e != 0) { + list.add(e); + } + } + return list2Array(list); + } + + /** + * 给定两个已经排序好的整形数组, 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) return null; + if (array1.length == 0) return Arrays.copyOf(array2, array2.length); + List list = array2List(array1); + int currentIndex = 0; + for (int e : array2) { + for (int index = currentIndex; index < list.size(); index++ ) { + currentIndex = index + 1; + if (list.get(index) == e) break; + if (list.get(index) > e) { + list.add(index, e); + break; + } + } + if (e > list.get(list.size()-1)) list.add(e); + } + return list2Array(list); + } + + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + * @throws Exception + */ + public int[] grow(int [] oldArray, int size) throws Exception{ + if (oldArray==null) return null; + if (size < 0) throw new Exception(); + int oldSize = oldArray.length; + int[] newArray = new int[size+oldSize]; + System.arraycopy(oldArray, 0, newArray, 0, oldSize); + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public int[] fibonacci(int max){ + if (max <= 1) return new int[0]; + int i = 1, j = 1; + List list = new ArrayList<>(); + list.add(i); + list.add(j); + int next = i+j; + while (max > next) { + list.add(next); + i = j; + j = next; + next = i+j; + } + return list2Array(list); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + // TODO 使用筛法,写的不好,有待改善 + if (max <= 2) return new int[0]; + List list = new ArrayList<>(); + int i; + for (i=2; i= 0) + list.remove(index); + k += currentNum; + } + currentNum = list.get(++i); + } + return list2Array(list); + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + List list = new ArrayList<>(); + int[] factors; + for (int i=1; i list = new ArrayList<>(); + for (int i=1; i < num; i++) { + if(num % i == 0) list.add(i); + } + return list2Array(list); + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param seperator + * @return + */ + public String join(int[] array, String seperator){ + if (array.length == 0) return ""; + if (array.length == 1) return "" + array[0]; + StringBuilder s = new StringBuilder(); + for (int i=0; i转换为相同顺序和长度的int[] + * @param list + * @return + */ + private int[] list2Array(List list) { + int size = list.size(); + int[] newArray = new int[size]; + for (int i=0; i + * @param array + * @return + */ + private List array2List(int[] array) { + List list = new ArrayList<>(); + for (int e : array) { + list.add(e); + } + return list; + } + + public static void main(String []args) throws Exception { + ArrayUtil arrayUtil = new ArrayUtil(); + + // merge + int[] a1 = {1,2,3}, a2 = {-4,-2,2,3,4}; +// int[] a1 = {}, a2 = {}; +// int[] a1 = {1,2,3}, a2 = {}; +// int[] a1 = {}, a2 = {1,2,3}; +// int[] a1 = {4,5,6}, a2 = {1,2,3}; + int[] a3 = arrayUtil.merge(a1, a2); + System.out.println(Arrays.toString(a3)); + + // reverse +// a1 = new int[] {}; +// a1 = new int[] {4,}; +// a1 = new int[] {4,3,5,6,7,7,8}; + a1 = new int[] {4,3,5,6,7,7,8, 9}; + arrayUtil.reverseArray(a1); + System.out.println(Arrays.toString(a1)); + + // remove zero +// a1 = new int[] {}; +// a1 = new int[] {0,0}; + a1 = new int[] {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; + a2 = arrayUtil.removeZero(a1); + System.out.println(Arrays.toString(a2)); + + // grow + a1 = new int[] {1,2,3}; + a2 = arrayUtil.grow(a1, 4); +// a2 = arrayUtil.grow(a1, 2); +// a2 = arrayUtil.grow(a1, 0); + System.out.println(Arrays.toString(a2)); + + // fibonacci + a1 = arrayUtil.fibonacci(15); +// a1 = arrayUtil.fibonacci(1); +// a1 = arrayUtil.fibonacci(2); +// a1 = arrayUtil.fibonacci(-2); + System.out.println(Arrays.toString(a1)); + + // prime + a1 = arrayUtil.getPrimes(2); +// a1 = arrayUtil.getPrimes(3); +// a1 = arrayUtil.getPrimes(8); +// a1 = arrayUtil.getPrimes(12); +// a1 = arrayUtil.getPrimes(23); +// a1 = arrayUtil.getPrimes(24); +// a1 = arrayUtil.getPrimes(50); + a1 = arrayUtil.getPrimes(100); + System.out.println(Arrays.toString(a1)); + + // perfectNumbers + a1 = arrayUtil.getPerfectNumbers(1000); + System.out.println(Arrays.toString(a1)); + + // join +// a1 = new int[] {}; +// a1 = new int[] {1}; + a1 = new int[] {1,2,3}; + String str = arrayUtil.join(a1, "-"); + System.out.println(str); + + } +} 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 97% 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 index c05f264c0b..9c17846b42 100644 --- 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 @@ -1,46 +1,46 @@ -package com.github.miniyk2012.coding2017.coderising.download; - -import com.github.miniyk2012.coding2017.coderising.download.api.Connection; -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CyclicBarrier; - -public class DownloadThread extends Thread{ - - Connection conn; - int startPos; - int endPos; - String fileName; - CyclicBarrier barrier; - - public DownloadThread(String name, Connection conn, int startPos, int endPos, String fileName, CyclicBarrier barrier){ - super(name); - this.conn = conn; - this.startPos = startPos; - this.endPos = endPos; - this.fileName = fileName; - this.barrier = barrier; - } - public void run(){ - try (RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd")) { - raf.seek(startPos); - byte[] buf = conn.read(startPos, endPos); -// String desc = Thread.currentThread().getName()+"startPos:"+startPos+",length:"+length + "buf size:"+buf.length; -// System.out.println(desc); - raf.write(buf, 0, buf.length); - if (null != barrier) { - barrier.await(); - } - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - } finally { - conn.close(); - } - } -} +package com.github.miniyk2012.coding2017.coderising.download; + +import com.github.miniyk2012.coding2017.coderising.download.api.Connection; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String fileName; + CyclicBarrier barrier; + + public DownloadThread(String name, Connection conn, int startPos, int endPos, String fileName, CyclicBarrier barrier){ + super(name); + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.fileName = fileName; + this.barrier = barrier; + } + public void run(){ + try (RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd")) { + raf.seek(startPos); + byte[] buf = conn.read(startPos, endPos); +// String desc = Thread.currentThread().getName()+"startPos:"+startPos+",length:"+length + "buf size:"+buf.length; +// System.out.println(desc); + raf.write(buf, 0, buf.length); + if (null != barrier) { + barrier.await(); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } finally { + conn.close(); + } + } +} 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 97% 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 index 94fa72e741..a0d76cbf92 100644 --- 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 @@ -1,118 +1,118 @@ -package com.github.miniyk2012.coding2017.coderising.download; - -import com.github.miniyk2012.coding2017.coderising.download.api.Connection; -import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionException; -import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionManager; -import com.github.miniyk2012.coding2017.coderising.download.api.DownloadListener; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - - -public class FileDownloader { - - private String url; - private String fileName; - private DownloadListener listener; - private ConnectionManager cm; - private int threadNum = 5; - private int length = 0; - private Connection conn; - - - 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方法 - - try (RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd")) { - conn = cm.open(this.url); - length = conn.getContentLength(); - raf.setLength(length); - threadPoolDownload(); -// oneThreadDownload(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - } - - 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(); - } - } - } - - 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; - } - - public DownloadListener getListener(){ - return this.listener; - } - -} +package com.github.miniyk2012.coding2017.coderising.download; + +import com.github.miniyk2012.coding2017.coderising.download.api.Connection; +import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionException; +import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionManager; +import com.github.miniyk2012.coding2017.coderising.download.api.DownloadListener; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + + +public class FileDownloader { + + private String url; + private String fileName; + private DownloadListener listener; + private ConnectionManager cm; + private int threadNum = 5; + private int length = 0; + private Connection conn; + + + 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方法 + + try (RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd")) { + conn = cm.open(this.url); + length = conn.getContentLength(); + raf.setLength(length); + threadPoolDownload(); +// oneThreadDownload(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + + } + + 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(); + } + } + } + + 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; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} 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 95% 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 index 9845729e18..93ad40bc91 100644 --- 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 @@ -1,24 +1,24 @@ -package com.github.miniyk2012.coding2017.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(); -} +package com.github.miniyk2012.coding2017.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(); +} 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 96% 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 index 7d185584dc..5fc42ce667 100644 --- 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 @@ -1,5 +1,5 @@ -package com.github.miniyk2012.coding2017.coderising.download.api; - -public class ConnectionException extends Exception { - -} +package com.github.miniyk2012.coding2017.coderising.download.api; + +public class ConnectionException extends Exception { + +} 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 95% 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 index 19bd1a092e..7477455e8c 100644 --- 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 @@ -1,13 +1,13 @@ -package com.github.miniyk2012.coding2017.coderising.download.api; - -import java.io.IOException; -import java.net.ProtocolException; - -public interface ConnectionManager { - /** - * 给定一个url , 打开一个连接 - * @param url - * @return - */ - Connection open(String url) throws ConnectionException; -} +package com.github.miniyk2012.coding2017.coderising.download.api; + +import java.io.IOException; +import java.net.ProtocolException; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + Connection open(String url) throws ConnectionException; +} 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 96% 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 index 1488a94f22..60c5c38ffe 100644 --- 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 @@ -1,5 +1,5 @@ -package com.github.miniyk2012.coding2017.coderising.download.api; - -public interface DownloadListener { - void notifyFinished(); -} +package com.github.miniyk2012.coding2017.coderising.download.api; + +public interface DownloadListener { + void notifyFinished(); +} 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 96% 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 index b928e0ced7..9076b09e60 100644 --- 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 @@ -1,64 +1,64 @@ -package com.github.miniyk2012.coding2017.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 com.github.miniyk2012.coding2017.basic.ArrayList; -import com.github.miniyk2012.coding2017.coderising.download.api.Connection; - -public class ConnectionImpl implements Connection{ - private HttpURLConnection downLoadConn; - private HttpURLConnection getLengthConn; - - public ConnectionImpl(URL urlObject) { - HttpURLConnection conn = null; - try { - downLoadConn = (HttpURLConnection) urlObject.openConnection(); - downLoadConn.setRequestMethod("GET"); - - getLengthConn = (HttpURLConnection) urlObject.openConnection(); - getLengthConn.setRequestMethod("GET"); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - @Override - public byte[] read(int startPos, int endPos) throws IOException { - 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() { - int len = getLengthConn.getContentLength(); - return len; - } - - @Override - public void close() { - downLoadConn.disconnect(); - getLengthConn.disconnect(); - } - -} +package com.github.miniyk2012.coding2017.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 com.github.miniyk2012.coding2017.basic.ArrayList; +import com.github.miniyk2012.coding2017.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + private HttpURLConnection downLoadConn; + private HttpURLConnection getLengthConn; + + public ConnectionImpl(URL urlObject) { + HttpURLConnection conn = null; + try { + downLoadConn = (HttpURLConnection) urlObject.openConnection(); + downLoadConn.setRequestMethod("GET"); + + getLengthConn = (HttpURLConnection) urlObject.openConnection(); + getLengthConn.setRequestMethod("GET"); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + 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() { + int len = getLengthConn.getContentLength(); + return len; + } + + @Override + public void close() { + downLoadConn.disconnect(); + getLengthConn.disconnect(); + } + +} 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 96% 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 index c7870f9127..6766335baf 100644 --- 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 @@ -1,23 +1,23 @@ -package com.github.miniyk2012.coding2017.coderising.download.impl; - -import com.github.miniyk2012.coding2017.coderising.download.api.Connection; -import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionException; -import com.github.miniyk2012.coding2017.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 urlObject; - try { - urlObject = new URL(url); - return new ConnectionImpl(urlObject); - } catch (IOException e) { - e.printStackTrace(); - throw new ConnectionException(); - } - } -} +package com.github.miniyk2012.coding2017.coderising.download.impl; + +import com.github.miniyk2012.coding2017.coderising.download.api.Connection; +import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionException; +import com.github.miniyk2012.coding2017.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 urlObject; + try { + urlObject = new URL(url); + return new ConnectionImpl(urlObject); + } catch (IOException e) { + e.printStackTrace(); + throw new ConnectionException(); + } + } +} 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 96% 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 index b89a242df6..b0322078ee 100644 --- 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 @@ -1,48 +1,48 @@ -package com.github.miniyk2012.coding2017.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 void setMessage(String message) { - this.message = 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"; - } - - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } - - @Override - public String toString() { - return "LoginAction [name=" + name + ", password=" + password + ", message=" + message + "]"; - } -} +package com.github.miniyk2012.coding2017.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 void setMessage(String message) { + this.message = 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"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } + + @Override + public String toString() { + return "LoginAction [name=" + name + ", password=" + password + ", message=" + message + "]"; + } +} 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 96% 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 index f283373b48..3a8bf9fbc9 100644 --- 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 @@ -1,48 +1,48 @@ -package com.github.miniyk2012.coding2017.coderising.litestruts; - -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @author liuxin - * - */ -public class LogoutAction{ - private String name ; - private String password; - private String message; - - public String getName() { - return name; - } - - public String getPassword() { - return password; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public String toString() { - return "LogoutAction [name=" + name + ", password=" + password + ", message=" + message + "]"; - } - - public String execute(){ - if("test".equals(name) && "1234".equals(password)){ - this.message = "logout successful"; - return "success"; - } - this.message = "logout failed,please check your user/pwd"; - return "error"; - } - - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } -} +package com.github.miniyk2012.coding2017.coderising.litestruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LogoutAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "LogoutAction [name=" + name + ", password=" + password + ", message=" + message + "]"; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "logout successful"; + return "success"; + } + this.message = "logout failed,please check your user/pwd"; + return "error"; + } + + 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/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 97% 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 index 54e8468077..523f43b275 100644 --- 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 @@ -1,173 +1,173 @@ -package com.github.miniyk2012.coding2017.coderising.litestruts; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.logging.Logger; -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.io.SAXReader; -import org.dom4j.Element; - - -public class Struts { - - /** dom4j object model representation of a xml document. Note: We use the interface(!) not its implementation */ - private static Document doc; - private static Element aElement; - private static Object object; - private static View view; - private static final Logger logger = Logger.getLogger(Struts.class.getName()); - - public static View runAction(String actionName, Map parameters) throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { - - /* - - 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字段中。 - - */ - - readXml(); - String retValue = processAction(actionName, parameters); - view = generateView(retValue); - return view; - } - - private static View generateView(String retValue) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - view = new View(); - Map map = getFields(); - String jsp = getJsp(retValue); - view.setParameters(map); - view.setJsp(jsp); - return view; - } - - private static String getJsp(String retValue) { - for (Iterator i = aElement.elementIterator( "result" ); i.hasNext();) { - Element result = (Element) i.next(); - if (result.attributeValue("name").equals(retValue)) { - return result.getText(); - } - } - return ""; - } - - /** - * @return - * @throws IntrospectionException - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - private static Map getFields() - throws IntrospectionException, IllegalAccessException, InvocationTargetException { - Map map = new HashMap<>(); - Class clazz = object.getClass(); - Field[] fields = object.getClass().getDeclaredFields();//获得属性 - for (Field field : fields) { - PropertyDescriptor pd = new PropertyDescriptor(field.getName(), - clazz); - Method getMethod = pd.getReadMethod();//获得get方法 - String value = (String) getMethod.invoke(object);//执行get方法返回一个Object - map.put(field.getName(), value); - } - return map; - } - - private static void readXml() throws DocumentException { - String fileName = Thread.currentThread().getContextClassLoader().getResource("").getPath() - + "com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml"; - File aFile = new File(fileName); - SAXReader xmlReader = new SAXReader(); - doc = xmlReader.read(aFile); - } - - private static String processAction(String actionName, Map parameters) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { - generateObject(actionName); - setFields(parameters); - return doExecute(); - } - - /** - * @return - * @throws NoSuchMethodException - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - private static String doExecute() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - Class c = object.getClass(); - Method method = c.getMethod("execute"); - String ret = (String) method.invoke(object); - return ret; - } - - /** - * @param parameters - * @throws NoSuchMethodException - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - private static void setFields(Map parameters) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - for (Map.Entry entry: parameters.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - key = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); - Class c = object.getClass(); - Method method = c.getMethod(key, String.class); - method.invoke(object, value); - } - } - - /** - * @param actionName - * @throws InstantiationException - * @throws IllegalAccessException - * @throws ClassNotFoundException - */ - private static void generateObject(String actionName) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - Element root = doc.getRootElement(); - String className = null; - for ( Iterator i = root.elementIterator(); i.hasNext(); ) { - Element actionElement = (Element) i.next(); - if (actionElement.attributeValue("name").equals(actionName)) { - aElement = actionElement; - className = actionElement.attributeValue("class"); - break; - } - } - if (className == null) throw new InstantiationException("no such className"); - object = Class.forName(className).newInstance(); - } - - - public static void main(String args[]) throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException - { - Map params = new HashMap(); - params.put("name","test"); - params.put("password","1234"); - View view = runAction("login", params); - logger.info(view.toString()); - } - -} +package com.github.miniyk2012.coding2017.coderising.litestruts; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.logging.Logger; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.io.SAXReader; +import org.dom4j.Element; + + +public class Struts { + + /** dom4j object model representation of a xml document. Note: We use the interface(!) not its implementation */ + private static Document doc; + private static Element aElement; + private static Object object; + private static View view; + private static final Logger logger = Logger.getLogger(Struts.class.getName()); + + public static View runAction(String actionName, Map parameters) throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + + /* + + 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字段中。 + + */ + + readXml(); + String retValue = processAction(actionName, parameters); + view = generateView(retValue); + return view; + } + + private static View generateView(String retValue) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + view = new View(); + Map map = getFields(); + String jsp = getJsp(retValue); + view.setParameters(map); + view.setJsp(jsp); + return view; + } + + private static String getJsp(String retValue) { + for (Iterator i = aElement.elementIterator( "result" ); i.hasNext();) { + Element result = (Element) i.next(); + if (result.attributeValue("name").equals(retValue)) { + return result.getText(); + } + } + return ""; + } + + /** + * @return + * @throws IntrospectionException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + private static Map getFields() + throws IntrospectionException, IllegalAccessException, InvocationTargetException { + Map map = new HashMap<>(); + Class clazz = object.getClass(); + Field[] fields = object.getClass().getDeclaredFields();//获得属性 + for (Field field : fields) { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), + clazz); + Method getMethod = pd.getReadMethod();//获得get方法 + String value = (String) getMethod.invoke(object);//执行get方法返回一个Object + map.put(field.getName(), value); + } + return map; + } + + private static void readXml() throws DocumentException { + String fileName = Thread.currentThread().getContextClassLoader().getResource("").getPath() + + "com/github/miniyk2012/coding2017/coderising/litestruts/struts.xml"; + File aFile = new File(fileName); + SAXReader xmlReader = new SAXReader(); + doc = xmlReader.read(aFile); + } + + private static String processAction(String actionName, Map parameters) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { + generateObject(actionName); + setFields(parameters); + return doExecute(); + } + + /** + * @return + * @throws NoSuchMethodException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + private static String doExecute() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Class c = object.getClass(); + Method method = c.getMethod("execute"); + String ret = (String) method.invoke(object); + return ret; + } + + /** + * @param parameters + * @throws NoSuchMethodException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + private static void setFields(Map parameters) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + for (Map.Entry entry: parameters.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + key = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); + Class c = object.getClass(); + Method method = c.getMethod(key, String.class); + method.invoke(object, value); + } + } + + /** + * @param actionName + * @throws InstantiationException + * @throws IllegalAccessException + * @throws ClassNotFoundException + */ + private static void generateObject(String actionName) + throws InstantiationException, IllegalAccessException, ClassNotFoundException { + Element root = doc.getRootElement(); + String className = null; + for ( Iterator i = root.elementIterator(); i.hasNext(); ) { + Element actionElement = (Element) i.next(); + if (actionElement.attributeValue("name").equals(actionName)) { + aElement = actionElement; + className = actionElement.attributeValue("class"); + break; + } + } + if (className == null) throw new InstantiationException("no such className"); + object = Class.forName(className).newInstance(); + } + + + public static void main(String args[]) throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException + { + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + View view = runAction("login", params); + logger.info(view.toString()); + } + +} 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 95% 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 index 46759e7d01..7dacd0d9fe 100644 --- 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 @@ -1,27 +1,27 @@ -package com.github.miniyk2012.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; - } - @Override - public String toString() { - return "View [jsp=" + jsp + ", parameters=" + parameters + "]"; - } -} +package com.github.miniyk2012.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; + } + @Override + public String toString() { + return "View [jsp=" + jsp + ", parameters=" + parameters + "]"; + } +} 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 96% 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 index 501326dae0..57173d687a 100644 --- 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 @@ -1,55 +1,55 @@ -package com.github.miniyk2012.coding2017.coderising.download; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionManager; -import com.github.miniyk2012.coding2017.coderising.download.api.DownloadListener; -import com.github.miniyk2012.coding2017.coderising.download.impl.ConnectionManagerImpl; - -public class FileDownloaderTest { - boolean downloadFinished = false; - private double time = 0; - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testDownload() { - - 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("还没有下载完成,休眠0.01秒"); - time += 0.01; - //休眠0.01秒 - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - System.out.println("下载完成!耗时"+time+"秒"); - - } -} +package com.github.miniyk2012.coding2017.coderising.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.miniyk2012.coding2017.coderising.download.api.ConnectionManager; +import com.github.miniyk2012.coding2017.coderising.download.api.DownloadListener; +import com.github.miniyk2012.coding2017.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + private double time = 0; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + 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("还没有下载完成,休眠0.01秒"); + time += 0.01; + //休眠0.01秒 + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!耗时"+time+"秒"); + + } +} 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..be04c297ad 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 @@ -1,75 +1,72 @@ -package com.github.miniyk2012.coding2017.coderising.litestruts; - -import java.beans.IntrospectionException; -import java.lang.reflect.InvocationTargetException; -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() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { - - 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, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { - 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")); - } - - @Test - public void testLogoutActionSuccess() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { - - String actionName = "logout"; - - Map params = new HashMap(); - params.put("name","test"); - params.put("password","1234"); - - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/welcome.jsp", view.getJsp()); - Assert.assertEquals("logout successful", view.getParameters().get("message")); - } - - @Test - public void testLogoutActionFailed() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { - String actionName = "logout"; - Map params = new HashMap(); - params.put("name","test"); - params.put("password","123456"); //密码和预设的不一致 - - View view = Struts.runAction(actionName,params); - - Assert.assertEquals("/jsp/error.jsp", view.getJsp()); - Assert.assertEquals("logout failed,please check your user/pwd", view.getParameters().get("message")); - } -} +package com.github.miniyk2012.coding2017.coderising.litestruts; + +import java.beans.IntrospectionException; +import java.lang.reflect.InvocationTargetException; +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() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + + 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, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + 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")); + } + + @Test + public void testLogoutActionSuccess() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + + String actionName = "logout"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/welcome.jsp", view.getJsp()); + Assert.assertEquals("logout successful", view.getParameters().get("message")); + } + + @Test + public void testLogoutActionFailed() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + String actionName = "logout"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/error.jsp", view.getJsp()); + Assert.assertEquals("logout failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" index 8dbfe95dda..0b256f8f4a 100644 --- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" +++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" @@ -2,4 +2,12 @@ public class ConnectionException extends Exception { + /** + * 自定义异常错误 + * @param string + */ + public ConnectionException(String string) { + + } + } diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" index 4cd0b3eab1..ee55a8cec0 100644 --- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" +++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" @@ -1,5 +1,6 @@ package com.coderising.download.api; public interface DownloadListener { + public void notifyFinished(); } diff --git a/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/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..e8aa61e5ae --- /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..23d9da57ba --- /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..b44cbd94de --- /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..1f185736f9 --- /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/group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/BinaryTreeNode.java similarity index 100% rename from group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java rename to group03/345943980/download-0335/src/main/java/com/coding/basic/BinaryTreeNode.java diff --git a/group04/120549547/base/src/com/coding/basic/Iterator.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/Iterator.java similarity index 100% rename from group04/120549547/base/src/com/coding/basic/Iterator.java rename to group03/345943980/download-0335/src/main/java/com/coding/basic/Iterator.java 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..e7b1387a32 --- /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/group12/446031103/src/com/coding/basic/List.java b/group03/345943980/download-0335/src/main/java/com/coding/basic/List.java similarity index 100% rename from group12/446031103/src/com/coding/basic/List.java rename to group03/345943980/download-0335/src/main/java/com/coding/basic/List.java 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..36e516e266 --- /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..a5a04de76d --- /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..0bf72df7e9 --- /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..94a7bcb477 --- /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..f2d9bb59af --- /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..4a882f016a --- /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..d4dc218fc4 --- /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..c6dfb515f9 --- /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..f6e4d5118f --- /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..cf0c238d67 --- /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..bb59a226ed --- /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/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..7eec659c28 --- /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..c0306838b6 --- /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..70d3eeb2cc --- /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; i7->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..6807142b28 --- /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..b311dfb1c6 --- /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..7516cdcf42 --- /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..0ac2adb6c8 --- /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..0509bed745 --- /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/group04/1020483199/1020483199Learning/.classpath b/group04/1020483199/1020483199Learning/.classpath index 3e0fb272a8..04cc82dc42 100644 --- a/group04/1020483199/1020483199Learning/.classpath +++ b/group04/1020483199/1020483199Learning/.classpath @@ -1,7 +1,7 @@ - + diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..ba70c84329 --- /dev/null +++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.loader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + /** + * class文件存储位置 + */ + String location = clzPaths.get(0); + File file = new File(location); + File[] files = file.listFiles(); + InputStream in = null; + byte[] bt = null; + + int size = 0; + for(File fileSon:files){ + /** + * 判断出为class文件时 + */ + if(fileSon.isFile() && fileSon.getName().endsWith("EmployeeV1.class")){ + try { + long length = fileSon.length(); + bt = new byte[(int) length]; + byte[] context = new byte[1024]; + in = new FileInputStream(fileSon); + int tempbyte; + while((tempbyte = in.read(context)) != -1){ + for(int i = 0;i < context.length;i++){ + System.arraycopy(context, 0, bt, size, tempbyte); + } + size = tempbyte; + } + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + }finally{ + if(in != null){ + try { + in.close(); + } catch (IOException e) { + } + } + } + + } + } + return bt; + } + + + public void addClassPath(String path) { + + clzPaths.add(path); + + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + for(int i = 0;i < clzPaths.size();i++){ + if(i == clzPaths.size() - 1){ + sb.append(clzPaths.get(i)); + break; + } + sb.append(clzPaths.get(i)).append(";"); + + } + return sb.toString(); + } + + + + + +} diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..7c7d1bb15a --- /dev/null +++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,91 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + static String path1 = "F:/myGithub/coding2017/group04/1020483199/FourthHomeWork/bin/com/coderising/jvm/test"; + static String path2 = "C:/temp"; + + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + + loader.addClassPath(path1); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > x > 5 > 4 > 5插入之后 + public void add(int index , Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p.next != null){ + k++; + p = p.next;//当前p为要插入位置的前一个节点 + } + + if(p != null){ + Node nd = new Node(o); + nd.next = p.next; + p.next = nd; + } + + size++; + + } + } + public Object get(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + Node p = head; + int k = 0; + while(k < index && p.next !=null){ + k++; + p = p.next; + } + return p.data; + } + //3 > 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > 4 > 5插入之后 + public Object remove(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + if(head == null){ + return null; + } + if(index == 0){ + head = head.next; + size--; + return head.data; + }else{ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p != null){ + k++; + p = p.next; + } + Node pn = p.next; + if(pn != null){ + p.next = pn.next; + size--; + return pn.data; + } + + } + } + return null; + } + + public int size(){ + + return size; + } + + public void addFirst(Object o){ + if(head != null){ + Node nd = new Node(o); + Node first = head; + head = nd; + first = nd.next; + } + } + public void addLast(Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(p.next != null && k < size - 1){ + p = p.next; + k++; + } + Node newNode = new Node(o); + p.next = newNode; + } + } + public Object removeFirst(){ + Node node = head; + if(head != null){ + head = head.next; + } + return node.data; + } + public Object removeLast(){ + Node p = head; + int k = 0; + while(p.next != null && k < size - 2){ + k++; + p = p.next; + } + + p.next = null; + return p.next; + } + public Iterator iterator(){ + return null; + } + + + private static class Node{ + Object data; + Node next; + + private Node(Object o){ + this.data = o; + this.next = null; + } + } + + /** + * 把该链表逆置 + * head head + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + /** + * 长度超过1的单链表需要逆转 + */ + if(head == null || head.next == null){ + return; + } + Stack st = new Stack(); + Node currentNode = head; + while(currentNode != null){ + st.push(currentNode); + Node nextNode = currentNode.next; + currentNode.next = null;//断开连接 + currentNode = nextNode; + } + + head = (Node) st.pop(); + currentNode = head; + while(!st.isEmpty()){ + Node nextNode = (Node) st.pop(); + currentNode.next = nextNode; + currentNode = nextNode; + } + } + + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int num = size / 2; + for(int i = 0; i < num; i++){ + removeFirst(); + } + } + + /** + * 从第i个元素开始,删除length个元素 ,注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i < 0 || i >= size){ + throw new IndexOutOfBoundsException(); + } + int len = size - i >= length ? length : size - i; + int k = 0; + while(k < len){ + remove(i); + k++; + } + + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] newList = new int[list.size()]; + for(int i = 0;i < list.size(); i++){ + newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString()); + } + return newList; + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + for(int j = 0;j < list.size();j++){ + this.remove(list.get(j)); + } + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(head == null){ + throw new RuntimeException("LinkedList is null"); + + } + Node currentNode = head; + Node preNode = head; + while(currentNode.next != null){ + currentNode = currentNode.next; + Object data = preNode.data; + while(currentNode.data == data){ + if(currentNode.next == null){ + preNode.next = null; + break; + } + preNode.next = currentNode.next; + size--; + currentNode = currentNode.next; + if(currentNode == null){ + break; + } + } + preNode = preNode.next; + } + } + /** + * 传入删除数据节点 + */ + public void remove(Object obj){ + if(head == null){ + throw new RuntimeException("linkedlist is nuull"); + + } + if(head.data.equals(obj)){ + head = head.next; + size--; + }else{ + Node pre = head; + Node currentNode = head.next; + while(currentNode != null){ + if(currentNode.data.equals(obj)){ + pre.next = currentNode.next; + size--; + } + pre = pre.next; + currentNode = currentNode.next; + } + } + } + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + Node node = head; + int start = -1; + int end = -1; + int i = 0; + while(node != null){ + if((Integer)node.data <= min){ + start = i; + } + if((Integer)node.data >= max){ + end = i; + break; + } + node = node.next; + i++; + } + if(start == -1){ + start = 0; + } + if(end == -1){ + end = size; + } + this.remove(start+1, end-start-1); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(list == null){ + return null; + } + + LinkedList newList = new LinkedList(); + int fi = 0; + int se = 0; + while(fi < this.size && se < list.size()){ + int val1 = (Integer) this.get(fi); + int val2 = (Integer) list.get(se); + if(val1 == val2){ + newList.add(val1); + fi++; + se++; + }else if(val1 < val2){ + fi++; + }else{ + se++; + } + + } + return newList; + } + + public static void main(String[] args) { + LinkedList linkedList = new LinkedList(); + linkedList.add(11); + linkedList.add(22); + linkedList.add(33); + linkedList.add(44); + linkedList.add(55); + linkedList.reverse(); + for(int i = 0; i < linkedList.size; i++){ + System.out.println(linkedList.get(i)); + } + } +} diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java new file mode 100644 index 0000000000..55ff205b5d --- /dev/null +++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java @@ -0,0 +1,9 @@ +package com.coding.basic.linkedList; + +public interface List { + public void add(Object o); + public void add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..e5ddb476a6 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,96 @@ +package com.coderising.array; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public void reverseArray(int[] origin){ + + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray){ + return null; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2){ + return null; + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public int[] grow(int [] oldArray, int size){ + return null; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public int[] fibonacci(int max){ + return null; + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + return null; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + return null; + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + return null; + } + + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..d16eca2319 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,42 @@ +package com.coderising.download; + + + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + + private Connection conn; + private int startPos; + private int endPos; + private String filePath; + private CyclicBarrier barrier; + + public DownloadThread(Connection conn, int startPos, int endPos,String filePath,CyclicBarrier barrier){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.filePath = filePath; + this.barrier = barrier; + } + public void run(){ + try { + System.out.println("线程" + this.getName() + "开始下载. startPos:" + startPos + "; endPos:" + endPos); + byte[] buffer = conn.read(startPos, endPos); + RandomAccessFile ra = new RandomAccessFile(filePath, "rw"); + ra.seek(startPos); + ra.write(buffer); + //关闭流 + ra.close(); + conn.close(); + barrier.await(); + System.out.println("线程" + this.getName() + "下载完成."); + }catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c6cdf3fc4a --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,139 @@ +package com.coderising.download; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CyclicBarrier; + +import org.junit.internal.runners.statements.RunAfters; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + + +public class FileDownloader { + + private String url; + + private String localFile; + + DownloadListener listener; + + ConnectionManager cm; + + private final static int thread_count = 3; + + public FileDownloader(String _url,String localFile) { + this.url = _url; + this.localFile = localFile; + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接, + //通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, + //调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, + //这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, + //然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, + //返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + CyclicBarrier barrier = new CyclicBarrier(thread_count, new Runnable() { + + @Override + public void run() { + listener.notifyFinished(); + } + }); + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + createPlaceHolderFile(this.localFile,length); + + int[] [] ranges = allowcateDownloadRange(thread_count,length); + + for(int i = 0; i < thread_count; i++){ + + DownloadThread thread= new DownloadThread(conn, ranges[i][0], ranges[i][1], localFile, barrier); + + thread.start(); + + } + + } catch (Exception e) { + e.printStackTrace(); + + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + private int[][] allowcateDownloadRange(int threadCount, int length) { + int[][] ranges = new int[thread_count][2]; + + int eachThreadSize = length / threadCount; + + int left = length % threadCount; + + for(int i = 0 ; i < thread_count;i++){ + int startPos = i * eachThreadSize; + + int endPos = (i+1) * eachThreadSize - 1; + + if((i==thread_count -1)){ + endPos += left; + } + + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + + return ranges; + } + + private void createPlaceHolderFile(String localfile, int length) throws IOException { + RandomAccessFile file = new RandomAccessFile(localfile, "rw"); + for(int i = 0;i < length ; i++){ + file.write(0); + } + file.close(); + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..7393f57040 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,90 @@ +package com.coderising.download; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testContentLength() throws Exception{ + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + Assert.assertEquals(35470, conn.getContentLength()); + } + + @Test + public void testRead() throws Exception{ + + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + + byte[] data = conn.read(0, 35469); + + Assert.assertEquals(35470, data.length); + + data = conn.read(0, 1023); + + Assert.assertEquals(1024, data.length); + + data = conn.read(1024, 2023); + + Assert.assertEquals(1000, data.length); + + + // 测试不充分,没有断言内容是否正确 + } + + @Test + public void testDownload() { + + String url = "http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + + FileDownloader downloader = new FileDownloader(url, "F:/picture/a.png"); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..105f00f03a --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,13 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + /** + * 自定义异常错误 + * @param string + */ + public ConnectionException(Exception e) { + super(e); + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..7b51663ff9 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,6 @@ +package com.coderising.download.api; + +public interface DownloadListener { + + public void notifyFinished(); +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..dcaf5883fa --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,89 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; + +class ConnectionImpl implements Connection { + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException{ + try { + url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + + HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); + + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + + endPos); + + InputStream is = httpConn.getInputStream(); + + //is.skip(startPos); + + byte[] buff = new byte[BUFFER_SIZE]; + + int totalLen = endPos - startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + while(baos.size() < totalLen){ + + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff,0, len); + } + + + if(baos.size() > totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + + URLConnection con; + try { + con = url.openConnection(); + + return con.getContentLength(); + + } catch (IOException e) { + e.printStackTrace(); + } + + return -1; + + + } + + @Override + public void close() { + + + } + +} \ No newline at end of file diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..3af9b21485 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,17 @@ +package com.coderising.download.impl; + +import java.net.MalformedURLException; +import java.net.URL; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group15/1502_1617273078/src/com/coderising/litestruts/LoginAction.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java similarity index 100% rename from group15/1502_1617273078/src/com/coderising/litestruts/LoginAction.java rename to group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..6df190d484 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,37 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + + public static View runAction(String actionName, Map parameters) { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + return null; + } + +} diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/StrutsTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java similarity index 100% rename from group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/StrutsTest.java rename to group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..3fe0a702d4 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java @@ -0,0 +1,27 @@ +package com.coderising.litestruts; + +import java.util.Map; + +public class View { + private String jsp; + + private Map parameters; + + public String getJsp() { + return jsp; + } + + public void setJsp(String jsp) { + this.jsp = jsp; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..1f185736f9 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData = new Object[100]; + + public void add(Object o){ + + } + public void add(int index, Object o){ + + } + + public Object get(int index){ + return null; + } + + public Object remove(int index){ + return null; + } + + public int size(){ + return -1; + } + + public Iterator iterator(){ + return null; + } + +} diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/BinaryTreeNode.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/BinaryTreeNode.java rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java diff --git a/group12/446031103/src/com/coding/basic/Iterator.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java similarity index 100% rename from group12/446031103/src/com/coding/basic/Iterator.java rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..7b10ffb8b6 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java @@ -0,0 +1,374 @@ +package com.coding.basic; + +import java.util.Stack; + +public class LinkedList implements List { + private int size; + + private Node head; + + public LinkedList(){ + size = 0; + + head = null; + } + + public void add(Object o){ + Node nd = new Node(o); + if(head == null){ + head = nd; + }else{ + Node p = head; + while(p.next != null){ + p = p.next; + } + p.next = nd; + } + size ++; + + } + //3 > 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > x > 5 > 4 > 5插入之后 + public void add(int index , Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p.next != null){ + k++; + p = p.next;//当前p为要插入位置的前一个节点 + } + + if(p != null){ + Node nd = new Node(o); + nd.next = p.next; + p.next = nd; + } + + size++; + + } + } + public Object get(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + Node p = head; + int k = 0; + while(k < index && p.next !=null){ + k++; + p = p.next; + } + return p.data; + } + //3 > 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > 4 > 5插入之后 + public Object remove(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + if(head == null){ + return null; + } + if(index == 0){ + head = head.next; + size--; + return head.data; + }else{ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p != null){ + k++; + p = p.next; + } + Node pn = p.next; + if(pn != null){ + p.next = pn.next; + size--; + return pn.data; + } + + } + } + return null; + } + + public int size(){ + + return size; + } + + public void addFirst(Object o){ + if(head != null){ + Node nd = new Node(o); + Node first = head; + head = nd; + first = nd.next; + } + } + public void addLast(Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(p.next != null && k < size - 1){ + p = p.next; + k++; + } + Node newNode = new Node(o); + p.next = newNode; + } + } + public Object removeFirst(){ + Node node = head; + if(head != null){ + head = head.next; + } + return node.data; + } + public Object removeLast(){ + Node p = head; + int k = 0; + while(p.next != null && k < size - 2){ + k++; + p = p.next; + } + + p.next = null; + return p.next; + } + public Iterator iterator(){ + return null; + } + + + private static class Node{ + Object data; + Node next; + + private Node(Object o){ + this.data = o; + this.next = null; + } + } + + /** + * 把该链表逆置 + * head head + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + /** + * 长度超过1的单链表需要逆转 + */ + if(head == null || head.next == null){ + return; + } + Stack st = new Stack(); + Node currentNode = head; + while(currentNode != null){ + st.push(currentNode); + Node nextNode = currentNode.next; + currentNode.next = null;//断开连接 + currentNode = nextNode; + } + + head = (Node) st.pop(); + currentNode = head; + while(!st.isEmpty()){ + Node nextNode = (Node) st.pop(); + currentNode.next = nextNode; + currentNode = nextNode; + } + } + + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int num = size / 2; + for(int i = 0; i < num; i++){ + removeFirst(); + } + } + + /** + * 从第i个元素开始,删除length个元素 ,注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i < 0 || i >= size){ + throw new IndexOutOfBoundsException(); + } + int len = size - i >= length ? length : size - i; + int k = 0; + while(k < len){ + remove(i); + k++; + } + + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] newList = new int[list.size()]; + for(int i = 0;i < list.size(); i++){ + newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString()); + } + return newList; + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + for(int j = 0;j < list.size();j++){ + this.remove(list.get(j)); + } + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(head == null){ + throw new RuntimeException("LinkedList is null"); + + } + Node currentNode = head; + Node preNode = head; + while(currentNode.next != null){ + currentNode = currentNode.next; + Object data = preNode.data; + while(currentNode.data == data){ + if(currentNode.next == null){ + preNode.next = null; + break; + } + preNode.next = currentNode.next; + size--; + currentNode = currentNode.next; + if(currentNode == null){ + break; + } + } + preNode = preNode.next; + } + } + /** + * 传入删除数据节点 + */ + public void remove(Object obj){ + if(head == null){ + throw new RuntimeException("linkedlist is nuull"); + + } + if(head.data.equals(obj)){ + head = head.next; + size--; + }else{ + Node pre = head; + Node currentNode = head.next; + while(currentNode != null){ + if(currentNode.data.equals(obj)){ + pre.next = currentNode.next; + size--; + } + pre = pre.next; + currentNode = currentNode.next; + } + } + } + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + Node node = head; + int start = -1; + int end = -1; + int i = 0; + while(node != null){ + if((Integer)node.data <= min){ + start = i; + } + if((Integer)node.data >= max){ + end = i; + break; + } + node = node.next; + i++; + } + if(start == -1){ + start = 0; + } + if(end == -1){ + end = size; + } + this.remove(start+1, end-start-1); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(list == null){ + return null; + } + + LinkedList newList = new LinkedList(); + int fi = 0; + int se = 0; + while(fi < this.size && se < list.size()){ + int val1 = (Integer) this.get(fi); + int val2 = (Integer) list.get(se); + if(val1 == val2){ + newList.add(val1); + fi++; + se++; + }else if(val1 < val2){ + fi++; + }else{ + se++; + } + + } + return newList; + } + + public static void main(String[] args) { + LinkedList linkedList = new LinkedList(); + linkedList.add(11); + linkedList.add(22); + linkedList.add(33); + linkedList.add(44); + linkedList.add(55); + linkedList.reverse(); + for(int i = 0; i < linkedList.size; i++){ + System.out.println(linkedList.get(i)); + } + } +} diff --git a/group14/187114392/work_1_20170225/src/com/coding/basic/List.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/List.java rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..36e516e266 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java @@ -0,0 +1,19 @@ +package com.coding.basic; + +public class Queue { + + public void enQueue(Object o){ + } + + public Object deQueue(){ + return null; + } + + public boolean isEmpty(){ + return false; + } + + public int size(){ + return -1; + } +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..a25d5b8024 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java @@ -0,0 +1,22 @@ +package com.coding.basic; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + } + + public Object pop(){ + return null; + } + + public Object peek(){ + return null; + } + public boolean isEmpty(){ + return false; + } + public int size(){ + return -1; + } +} diff --git a/group04/120549547/base/buil.bat b/group04/120549547/base/buil.bat deleted file mode 100644 index 7164a42ac0..0000000000 --- a/group04/120549547/base/buil.bat +++ /dev/null @@ -1,5 +0,0 @@ -javac -sourcepath src -d classes -encoding utf-8 src\com\coding\basic\*.java - -java -cp classes com.coding.basic.Main - -pause \ No newline at end of file diff --git a/group04/120549547/base/src/com/coding/basic/ArrayList.java b/group04/120549547/base/src/com/coding/basic/ArrayList.java deleted file mode 100644 index 56e7aa4c26..0000000000 --- a/group04/120549547/base/src/com/coding/basic/ArrayList.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.coding.basic; -import java.util.Arrays; - -public class ArrayList implements List { - /*默认数组容量*/ - public static final int DEFAULT_CAPCATITY = 10; - - /*数组元素个数*/ - private int size; - - private Object[] elementData; - - public ArrayList(){ - this(DEFAULT_CAPCATITY); - } - - public ArrayList(int capacity){ - if (capacity<0 || capacity>Integer.MAX_VALUE) - throw new IllegalArgumentException("非法容量: " + capacity); - elementData = new Object[capacity]; - } - - - public void add(Object o){ - /*判断是否需要扩容*/ - ensureCapacity(size + 1); - elementData[size++] = o; - } - - public void add(int index, Object o){ - checkIndex(index); - /*判断是否需要扩容*/ - ensureCapacity(size + 1); - /*将index->size的元素依次向右移一个位置*/ - System.arraycopy(elementData, index, elementData, index+1, size-index); - /*插入o的值*/ - elementData[index] = o; - size++; - } - - - public Object get(int index){ - - checkIndex(index); - return elementData[index]; - } - - public Object remove(int index){ - - checkIndex(index); - Object value = elementData[index]; - /*将index+1 -> size的元素依次向左移一个位置*/ - System.arraycopy(elementData,index+1, elementData, index, size-index-1); - elementData[--size]=null; //释放最后一个元素,同时size减一; - return value; - } - - public int size(){ - return this.size; - } - - public Iterator iterator(){ - return null; - } - /* 确认容量是否足够,也可以直接调用手动扩容*/ - public void ensureCapacity(int minCapacity){ - int oldCapacity = elementData.length; - /*容量不足需要扩容*/ - if(oldCapacity < minCapacity){ - int newCapacity = oldCapacity * 2; //扩大2倍 - if (newCapacity < minCapacity){ - newCapacity = minCapacity; //扩容后仍不足,取最大值 - } - System.out.println("数据扩容至: " + newCapacity); - elementData = Arrays.copyOf(elementData, newCapacity); - } - - } - - private void checkIndex(int index){ - if (index<0 || index>= size) - throw new IndexOutOfBoundsException ("index非法: " + index); - } - @Override - public String toString(){ - - StringBuffer sb = new StringBuffer(""); - for(int i=0; i "); - } - return sb.toString(); - } -} diff --git a/group04/120549547/base/src/com/coding/basic/LinkedList.java b/group04/120549547/base/src/com/coding/basic/LinkedList.java deleted file mode 100644 index edfbcc1007..0000000000 --- a/group04/120549547/base/src/com/coding/basic/LinkedList.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.coding.basic; - -public class LinkedList implements List { - - private Node head; - private int size; - /*创建一个带头节点的单链表*/ - public LinkedList(){ - head = new Node(null); - } - - /*添加一个元素(尾插法)*/ - public void add(Object o){ - - Node node = new Node(o); - Node pos = head; - //找到最后一个元素位置 - while(pos.next != null){ - pos = pos.next; - } - pos.next = node; - size++; - - } - - /*在index位置插入*/ - public void add(int index , Object o){ - //判断索引是否合法 - checkIndex(index); - Node node = new Node(o); - Node pos = head; - //找到插入位置 - while(index-- != 0){ - pos = pos.next; - } - node.next = pos.next; - pos.next = node; - size++; - - } - public Object get(int index){ - checkIndex(index); - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - Node pos = head.next; //pos指向要获取的节点 - while(index-- !=0){ - pos = pos.next; - } - - return pos.data; - } - public Object remove(int index){ - checkIndex(index); - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - - Node pos = head; //pos指向要删除的前一个结点 - while(index-- != 0){ - pos = pos.next; - } - Node value = pos.next; //要删除的节点 - pos.next = value.next; - size--; - return value.data; - - - } - - public int size(){ - return size; - } - - public void addFirst(Object o){ - - } - public void addLast(Object o){ - this.add(o); - } - public Object removeFirst(){ - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - return remove(0); - } - public Object removeLast(){ - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - return remove(size-1); - } - - public boolean isEmpty(){ - return size == 0; - } - public Iterator iterator(){ - return null; - } - - private void checkIndex(int index){ - if (index<0 || index>=size ){ - throw new IllegalArgumentException ("index不合法: " + index ); - } - } - - @Override - public String toString(){ - - StringBuffer sb = new StringBuffer(""); - for(int i=0; i "); - } - return sb.toString(); - } - - private static class Node{ - public Object data; - public Node next; - - public Node(Object data){ - this.data = data; - this.next = null; - } - - } -} diff --git a/group04/120549547/base/src/com/coding/basic/Main.java b/group04/120549547/base/src/com/coding/basic/Main.java deleted file mode 100644 index de8a0b0990..0000000000 --- a/group04/120549547/base/src/com/coding/basic/Main.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.coding.basic; -import com.coding.basic.*; - -class Main{ - - public static void main(String[] args){ - System.out.println("数组测试开始"); - ArrayListTest(); - System.out.println("----------------分割线----------------"); - System.out.println("链表测试开始"); - LinkedListTest(); - System.out.println("----------------分割线----------------"); - System.out.println("栈测试开始"); - StatckTest(); - System.out.println("----------------分割线----------------"); - System.out.println("队测试开始"); - QueueTest(); - } - - public static void ArrayListTest(){ - ArrayList list = new ArrayList(2); - list.add("HelloBobi0"); - list.add("HelloBobi1"); - list.add("HelloBobi2"); - list.add("HelloBobi3"); - list.add("HelloBobi4"); - list.add("HelloBobi5"); - System.out.println((String)list.get(0)); - System.out.println((String)list.get(4)); - list.add(3, "Hei Man"); - list.remove(5); - System.out.println(list); - System.out.println("size:=" + list.size()); - } - - public static void LinkedListTest(){ - LinkedList ll = new LinkedList(); - - - ll.add("SingleDog0"); - ll.add("SingleDog1"); - ll.add("SingleDog2"); - ll.add("SingleDog3"); - ll.add("SingleDog4"); - ll.add("SingleDog5"); - - System.out.println((String)(ll.get(1))); - System.out.println(ll); - System.out.println("size:=" + ll.size()); - ll.remove(0); - ll.removeFirst(); - ll.removeLast(); - System.out.println(ll); - } - - public static void StatckTest(){ - Stack stack = new Stack(); - stack.push("虾师傅0"); - stack.push("虾师傅1"); - stack.push("虾师傅2"); - stack.push("虾师傅3"); - stack.push("虾师傅4"); - - stack.pop(); - System.out.println(stack.peek()); - System.out.println(stack); - - } - public static void QueueTest(){ - Queue queue = new Queue(); - queue.enQueue("龙师傅0"); - queue.enQueue("龙师傅1"); - queue.enQueue("龙师傅2"); - queue.enQueue("龙师傅3"); - queue.enQueue("龙师傅4"); - - System.out.println(queue.deQueue()); - System.out.println(queue.deQueue()); - System.out.println(queue.deQueue()); - System.out.println(queue.deQueue()); - System.out.println(queue.size()); - - - } -} \ No newline at end of file diff --git a/group04/120549547/base/src/com/coding/basic/Queue.java b/group04/120549547/base/src/com/coding/basic/Queue.java deleted file mode 100644 index 8f86f7492c..0000000000 --- a/group04/120549547/base/src/com/coding/basic/Queue.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.coding.basic; -import com.coding.basic.*; -public class Queue { - private LinkedList list; - - public Queue(){ - list = new LinkedList(); - } - /*入队*/ - public void enQueue(Object o){ - list.addLast(o); - } - - /*出队*/ - public Object deQueue(){ - if (isEmpty()){ - System.out.println("队空"); - } - return list.removeFirst(); - } - - public boolean isEmpty(){ - return list.isEmpty(); - } - - public int size(){ - return list.size(); - } -} diff --git a/group04/120549547/base/src/com/coding/basic/Stack.java b/group04/120549547/base/src/com/coding/basic/Stack.java deleted file mode 100644 index f7d3bba3db..0000000000 --- a/group04/120549547/base/src/com/coding/basic/Stack.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.coding.basic; -import com.coding.basic.LinkedList; - -public class Stack { - private LinkedList list; - - public Stack(){ - list = new LinkedList(); - } - - public void push(Object o){ - list.addLast(o); - } - - public Object pop(){ - if(isEmpty()){ - System.out.println("栈空"); - } - return list.removeLast(); - - } - - public Object peek(){ - return list.get(list.size()-1); - } - public boolean isEmpty(){ - return list.isEmpty(); - } - public int size(){ - return list.size(); - } - - @Override - public String toString(){ - return list.toString(); - } -} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class BinaryTreeNode { + + private Object data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public Object getData() { + return data; + } + public void setData(Object data) { + this.data = data; + } + public BinaryTreeNode getLeft() { + return left; + } + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + public BinaryTreeNode getRight() { + return right; + } + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(Object o){ + return null; + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..31d6470bef --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java @@ -0,0 +1,8 @@ +package com.coding.basic; + +public interface Iterator { + boolean hasNext(); + + T next(); + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/List.java b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java new file mode 100644 index 0000000000..70a783968e --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java @@ -0,0 +1,31 @@ +package com.coding.basic; + +public interface List{ + int size(); + + boolean isEmpty(); + + boolean contains(Object o); + + Object[] toArray(); + + boolean add(T o); + + boolean remove(T o); + + void clear(); + + T get(int index); + + T set(int index, T o); + + void add(int index, T o); + + T remove(int index); + + int indexOf(T o); + + Iterator iterator(); + + void printf(); +} diff --git a/liuxin/data-structure/src/com/coding/basic/Stack.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java similarity index 100% rename from liuxin/data-structure/src/com/coding/basic/Stack.java rename to group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java new file mode 100644 index 0000000000..6c392a3618 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java @@ -0,0 +1,155 @@ +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +import java.util.Objects; + +public class ArrayList implements List { + + private int size; + private Object[] dataArray = new Object[0]; + + public int size() { + return this.size; + } + + public boolean isEmpty() { + return this.size == 0; + } + + public boolean contains(Object o) { + for (Object obj : dataArray) { + if (Objects.equals(obj, o)){ + return true; + } + } + return false; + } + + public Object[] toArray() { + Object[] array = new Object[size]; + System.arraycopy(dataArray, 0, array, 0, size); + return array; + } + + public boolean add(T o) { + ensureCapacity(size+1); + dataArray[size] = o; + size++; + return true; + } + + + + public boolean remove(T o) { + int index = indexOf(o); + if (index < 0){ + return false; + } + + System.arraycopy(dataArray, index + 1, dataArray, index, size - 1 - index); + dataArray[size - 1] = null; + size--; + return true; + } + + public void clear() { + for (int i = 0; i < size; i++) { + dataArray[i] = null; + } + size = 0; + } + @SuppressWarnings("unchecked") + public T get(int index) { + if (index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + + return (T) dataArray[index]; + } + + public T set(int index, T o) { + if (index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + dataArray[index] = o; + return o; + } + + public void add(int index, T o) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException(); + } + ensureCapacity(size + 1); + System.arraycopy(dataArray, index, dataArray, index + 1, size - index); + + dataArray[index] = o; + + size++; + } + + public T remove(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + T removeData = (T) dataArray[index]; + System.arraycopy(dataArray, index + 1, dataArray, index, size - index -1 ); + dataArray[size - 1] = null; + size--; + return removeData; + } + + public int indexOf(T o) { + for (int i = 0; i < size; i++) { + if (Objects.equals(o, dataArray[i])){ + return i; + } + } + return -1; + } + + public Iterator iterator() { + return new ArrayListIterator(); + } + + @Override + public void printf() { + for (int i = 0; i < size; i++) { + if (i == size - 1){ + System.out.print(dataArray[i]); + }else { + System.out.print(dataArray[i] + "->"); + } + } + } + + private void ensureCapacity(int minCapacity) { + if (minCapacity > dataArray.length){ + int newCapacity = Math.max(minCapacity, dataArray.length * 2); + Object[] newDataArray = new Object[newCapacity]; + System.arraycopy(dataArray, 0, newDataArray, 0, dataArray.length); + dataArray = newDataArray; + } + + } + + + private class ArrayListIterator implements Iterator { + + private int pos; + + @Override + public boolean hasNext() { + return pos < size(); + } + + @Override + public T next() { + if (hasNext()){ + return get(pos++); + } + return null; + } + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..411b60990b --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,269 @@ +package com.coding.basic.array; + +import java.util.Arrays; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public static void reverseArray(int[] origin){ + + if (origin == null || origin.length == 0){ + return; + } + + int temp ; + for (int i = 0; i < (origin.length / 2); i++) { + temp = origin[i]; + origin[i] = origin[(origin.length - 1) - i]; + origin[(origin.length - 1)- i] = temp; + } + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public static int[] removeZero(int[] oldArray){ + if (oldArray == null ){ + return null; + } + + if (oldArray.length == 0){ + return oldArray; + } + + int count = 0; + int[] temp = new int[oldArray.length]; + + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] != 0){ + temp[count++] = oldArray[i]; + } + } + + int[] result = new int[count]; + + System.arraycopy(temp, 0, result, 0, count); + return result; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public static int[] merge(int[] array1, int[] array2){ + if (array1 == null && array2 == null){ + return null; + } + + if (array1 == null){ + return array2; + } + + if (array2 == null){ + return array1; + } + + int length1 = array1.length; + int length2 = array2.length; + int[] temp = new int[length1 + length2]; + int i,j,k; + for ( i = 0, j = 0, k = 0; i < length1 && j < length2 ;) { + + if (array1[i] < array2[j]){ + temp[k++] = array1[i++]; + }else if (array1[i] > array2[j]){ + temp[k++] = array2[j++]; + }else { + temp[k++] = array1[i]; + i++; + j++; + } + } + + while (i < length1){ + temp[k++] = array1[i++]; + } + + while (j < length2){ + temp[k++] = array2[j++]; + } + int[] result = new int[k]; + System.arraycopy(temp, 0, result, 0, k); + return result; + + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public static int[] grow(int [] oldArray, int size){ + + int oldSize = oldArray.length; + int[] newArray = new int[oldSize + size]; + + System.arraycopy(oldArray, 0, newArray, 0, oldSize); + + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public static int[] fibonacci1(int max){ + if (max == 1){ + return new int[0]; + } + + int[] temp = new int[max]; + int count = 0; +// for (int i = 1; i < max; i++) { +// int num = fibonacci(i); +// if (num < max){ +// temp[count++] = num; +// }else { +// break; +// } +// } + temp[0] = 1; + temp[1] = 2; + for (int i = 2; i < max; i++) { + temp[i] = temp[i-1] + temp[i-2]; //直接在数组中实现斐波那契数列 + if (temp[i] >= max){ + break; + }else { + count++; + } + } + + + + return Arrays.copyOf(temp, count); + } + + private static int fibonacci(int n){ + if (n <= 0){ + throw new IllegalArgumentException(); + } + + if (n == 1 || n == 2) { + return 1; + } + + return fibonacci(n - 1) + fibonacci(n - 2); + + } + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public static int[] getPrimes(int max){ + + if (max <= 2){ + return new int[0]; + } + + int[] temp = new int[max]; + + int count = 0; + for (int i = 2; i < max; i++) { + int j; + for ( j = 2; j * j < i; j++) { + if (i % j == 0){ + break; + } + } + + if (j * j >= i){ + temp[count++] = i; + } + } + + return Arrays.copyOf(temp, count); + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public static int[] getPerfectNumbers(int max){ + if ( max <= 1){ + return new int[0]; + } + + ArrayList array = new ArrayList<>(); + for (int i = 2; i < max; i++) { + int sum = 0; //存储因子和 + for (int j = 1; j < i; j++) { + if (i % j == 0){ + sum += j; + } + } + + if (sum == i){ + array.add(i); + } + } + int[] result = new int[array.size()]; + + for (int i = 0; i < array.size(); i++) { + result[i] = array.get(i); + } + return result; + + + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public static String join(int[] array, String seperator){ + + if (array == null || array.length == 0){ + return null; + } + + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < array.length-1; i++) { + sb.append(array[i]).append(seperator); + } + + sb.append(array[array.length-1]); + + return sb.toString(); + } + + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..a4f2c14606 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,60 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + } + + private int capacity; + + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + + + } + + + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..eb128c4b24 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,369 @@ +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +import java.util.Objects; + +public class LinkedList implements List { + private int size; + + private Node head; + + private Node last; + + + + private static class Node { + T data; + Node pre; + Node next; + + Node(T data) { + this.data = data; + } + + + } + + public LinkedList(){ + this.head = new Node<>(null); + } + + @Override + public int size() { + return this.size; + } + + @Override + public boolean isEmpty() { + return this.size == 0; + } + + @Override + public boolean contains(Object o) { + Node node = this.head; + while (node.next != null){ + if (Objects.equals(node.data, o)){ + + return true; + } + node = node.next; + } + return false; + } + + @Override + public Object[] toArray() { + Object[] dataArray = new Object[size]; + Node node = head.next; + for (int i = 0; i < size&& node != null; i++, node = node.next) { + dataArray[i] = node.data; + + } + return dataArray; + } + + @Override + public boolean add(T o) { + if (this.last == null){ + this.last = new Node<>(o); + this.last.pre = this.head; + this.head.next = this.last; + }else { + Node oldLast = this.last; + this.last = new Node<>(o); + this.last.pre = oldLast; + oldLast.next = this.last; + + } + this.size++; + return true; + } + @SuppressWarnings("unchecked") + @Override + public boolean remove(T o) { + + + Node curNode = head.next; + Node preNode; + while (curNode != null){ + preNode = curNode.pre; //指向前一个节点 + + if (Objects.equals(curNode.data, o)){ + removeNode(preNode, curNode); + return true; + } + curNode = curNode.next; + } + + return false; + } + + private void removeNode(Node preNode, Node node) { + + if (this.last == node){ //如果删除的是last节点的情况 + if (preNode == this.head){ //如果只有一个节点的情况 + this.last = null; + }else { + this.last = preNode; + } + }else { + node.next.pre = node.pre; + + } + preNode.next = node.next; + + + + + this.size--; + } + + @Override + @SuppressWarnings("unchecked") + public void clear() { + for (Node x = head; x != null;){ + Node next = x.next; + x.data = null; + x.pre = null; + x.next = null; + x = next; + } + head = last = null; + size = 0; + + } + + @Override + @SuppressWarnings("unchecked") + public T get(int index) { + return (T) getNode(index).data; + } + + + + @Override + public T set(int index, T o) { + Node node = getNode(index); + node.data = o; + return o; + } + + @SuppressWarnings("unchecked") + @Override + public void add(int index, T o) { + ensureIndex(index); + Node newNode = new Node<>(o); + Node curNode = getNode(index); + Node pre = curNode.pre; + + newNode.next = curNode; + newNode.pre = pre; + curNode.pre = newNode; + pre.next = newNode; + + size++; + + } + + @Override + public T remove(int index) { + Node node = getNode(index); + Node pre = node.pre; + if (node == last){ //如果是最后一个节点 + if (pre != head){ //如果是唯一节点 + last = null; + }else { + last = node.pre; + } + } + + pre.next = node.next; + if (node.next != null){ + node.next.pre = pre; + } + size--; + return (T) node.data; + } + + @Override + public int indexOf(T o) { + Node node = head; + int index = 0; + + while (node.next != null){ + node = node.next; + if (Objects.equals(node.data, o)){ + return index; + } + index ++; + } + return index; + } + + @Override + public Iterator iterator() { + return new LinkedListIterator(); + } + + @Override + public void printf() { + Node node = head.next; + while (node != null){ + if (node.next != null) { + System.out.print(node.data + " -> "); + }else { + System.out.print(node.data); + } + node = node.next; + } + System.out.println(); + System.out.println("head = " + head); + System.out.println("last = " + last); + + } + + + private Node getNode(int index) { + ensureIndex(index); + Node node = this.head; + for (int i = 0; i <= index; i++) { + node = node.next; + } + return node; + } + + private void ensureIndex(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if (head.next == null && head.next.next == null){ //如果链表为空或者只有一个元素,不做变换 + return; + } + + last = head.next; + + Node pre = head.next; + Node cur = pre.next; + Node next; + pre.next = null; + while (cur != null){ + next = cur.next; + cur.next = pre; + pre = cur; + cur = next; + } + head.next = pre; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if (isEmpty()){ + return; + } + int halfIndex = size / 2; + + if (halfIndex >= 0){ + head.next = getNode(halfIndex); + } + + size = size - halfIndex; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + ensureIndex(i); + ensureIndex(i + length - 1); + + for (int j = i; j < i + length; j++) { + remove(i); + } + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + return null; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + return null; + } + + private class LinkedListIterator implements Iterator { + private Node node; + + LinkedListIterator(){ + node = head; + } + @Override + public boolean hasNext() { + return node.next != null; + } + + @Override + public T next() { + if (hasNext()){ + node = node.next; + return (T) node.data; + } + return null; + } + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java new file mode 100644 index 0000000000..db2047f096 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java @@ -0,0 +1,97 @@ +package com.coding.basic.queue; + +import java.util.NoSuchElementException; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ArrayQueue implements Queue { + + private int size; + private Object[] dataArray; + private int front; + private int rear; + + public ArrayQueue(int Capacity) { + this.dataArray = new Object[Capacity]; + this.front = 0; + this.rear = 0; + this.size = 0; + } + + @Override + public boolean add(T t) { + if (offer(t)){ + return true; + }else { + throw new IllegalStateException(); + } + } + + @Override + public boolean offer(T t) { + if (size >= dataArray.length){ + return false; + } + + dataArray[rear++] = t; + + if (rear == dataArray.length){ + rear = 0; + } + + size++; + return true; + } + + @Override + public T remove() { + T value = poll(); + if (value != null){ + return value; + }else { + throw new NoSuchElementException(); + } + } + + @Override + public T poll() { + if (size == 0){ + return null; + } + + + T value = (T) dataArray[front++]; + if (front == dataArray.length){ + front = 0; + } + + size--; + return value; + + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + + @Override + public T peek() { + if (size == 0){ + return null; + }else { + return (T) dataArray[front]; + } + } + + public void printf() { + for (int i = 0; i < size; i++) { + + System.out.print(dataArray[(front + i) % dataArray.length] + " "); + } + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java new file mode 100644 index 0000000000..64f86616f4 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java @@ -0,0 +1,16 @@ +package com.coding.basic.queue; + +public interface Queue { + + boolean add(T t); + + boolean offer(T t); + + T remove(); + + T poll(); + + boolean isEmpty(); + + T peek(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java new file mode 100644 index 0000000000..9fc2c860d2 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java @@ -0,0 +1,21 @@ +package com.coding.download; + + +import com.coding.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + + public DownloadThread( Connection conn, int startPos, int endPos){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ + + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java new file mode 100644 index 0000000000..ec975a9aae --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java @@ -0,0 +1,73 @@ +package com.coding.download; + + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + new DownloadThread(conn,0,length-1).start(); + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java new file mode 100644 index 0000000000..84fbc8afa2 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.coding.download; + +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; +import com.coding.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://localhost:8080/test.jpg"; + + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java new file mode 100644 index 0000000000..65f3dae9c5 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coding.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java new file mode 100644 index 0000000000..1db8b093ec --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coding.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1d1a83caf2 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coding.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java new file mode 100644 index 0000000000..c41045b0e8 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coding.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..0ddbf36e1b --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java @@ -0,0 +1,28 @@ +package com.coding.download.impl; + +import com.coding.download.api.Connection; + +import java.io.IOException; + + +public class ConnectionImpl implements Connection { + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + return null; + } + + @Override + public int getContentLength() { + + return 0; + } + + @Override + public void close() { + + + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..0f1c658a60 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,16 @@ +package com.coding.download.impl; + + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return null; + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java new file mode 100644 index 0000000000..26799a83a4 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java @@ -0,0 +1,124 @@ +package com.coding.litestruts; + + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class Configuration { + Map actions = new HashMap<>(); + + + + public Configuration(String path) throws IOException { + + URL pathName = Configuration.class.getClassLoader().getResource(path); + + assert pathName != null; +// InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); 默认则是从ClassPath根下获取,path不能以’/'开头 +// InputStream is = this.getClass().getResourceAsStream("/" + path); // path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取 +// InputStream is = pathName.openStream(); + InputStream is = new FileInputStream(pathName.getPath()); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void parseXML(InputStream is) { + + SAXReader reader = new SAXReader(); + + try { + + Document doc = reader.read(is); + Element root = doc.getRootElement(); + Iterator it = root.elementIterator("action"); + + while (it.hasNext()){ + + Element ActionElement = (Element) it.next(); + + String actionName = ActionElement.attributeValue("name"); + String className = ActionElement.attributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, className); + + Iterator it2 = ActionElement.elementIterator(); + + while (it2.hasNext()){ + + Element resultElement = (Element) it2.next(); + + String resultName = resultElement.attributeValue("name"); + String viewName = resultElement.getTextTrim(); + + ac.addViewResult(resultName, viewName); + } + + this.actions.put(actionName, ac); + } + } catch (DocumentException e) { + e.printStackTrace(); + } + } + + public String getClassName(String actionName) { + ActionConfig ac = actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getClassName(); + } + + public String getResultView(String actionName, String resultName) { + ActionConfig ac = actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getViewName(resultName); + + } + + + private static class ActionConfig{ + String name; + String clzName; + Map viewResult = new HashMap<>(); + + public ActionConfig(String name, String clzName) { + this.name = name; + this.clzName = clzName; + } + + public String getClassName() { + return clzName; + } + + public void addViewResult(String name, String viewName){ + viewResult.put(name, viewName); + + } + + public String getViewName(String resultName){ + return viewResult.get(resultName); + } + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java new file mode 100644 index 0000000000..39354518df --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package com.coding.litestruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..6b761355b1 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java @@ -0,0 +1,85 @@ +package com.coding.litestruts; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + + return getMethods(clz, "set"); + } + + public static void setParameters(Object o, Map params) { + + List methods = getSetterMethods(o.getClass()); + + for (String name : params.keySet()) { + + String methodName = "set" + name; + + for (Method method : methods) { + + if (method.getName().equalsIgnoreCase(methodName)){ + try { + method.invoke(o,params.get(name)); + + + + + + + } catch (IllegalAccessException | InvocationTargetException e) { + + e.printStackTrace(); + } + } + } + } + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz, "get"); + } + + private static List getMethods(Class clz, String startWithName) { + List methods = new ArrayList<>(); + + for (Method method : clz.getDeclaredMethods()) { + + if (method.getName().startsWith(startWithName)) { + methods.add(method); + } + } + return methods; + } + + public static Map getParamterMap(Object o) { + Map params = new HashMap<>(); + + List methods = getGetterMethods(o.getClass()); //获得"getXXX"方法 + + for (Method method : methods) { + + String methodName = method.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); //获得属性名 + + try { + params.put(name,method.invoke(o)); //将属性名 和属性值添加进去 + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + return params; + + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java new file mode 100644 index 0000000000..f446bec31c --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java @@ -0,0 +1,67 @@ +package com.coding.litestruts; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + + + public static View runAction(String actionName, Map parameters) throws NoSuchMethodException, IOException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + try { + Configuration cfg = new Configuration("struts.xml"); + + String clzName = cfg.getClassName(actionName); + if (clzName == null) { + return null; + } + String classPath = Struts.class.getClassLoader().getResource("").getPath(); + + System.out.println("clzName = " + clzName); + System.out.println("classPath = " + classPath); + Class clz = Class.forName(clzName); + + Object o = clz.newInstance(); + ReflectionUtil.setParameters(o, parameters); //将参数注入属性 + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String) m.invoke(o); //执行execute方法 + + Map params = ReflectionUtil.getParamterMap(o); //根据action获取model参数 + + String jsp = cfg.getResultView(actionName, resultName); //通过返回结果去拿视图名 + + View view = new View(); + view.setJsp(jsp); + view.setParameters(params); + return view; + } catch (IOException | InstantiationException | NoSuchMethodException | InvocationTargetException | ClassNotFoundException | IllegalAccessException e) { + e.printStackTrace(); + throw e; + } + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java new file mode 100644 index 0000000000..041fa4d889 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java @@ -0,0 +1,47 @@ +package com.coding.litestruts; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } + + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java new file mode 100644 index 0000000000..b6e795aa4a --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coding.litestruts; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java new file mode 100644 index 0000000000..abd49e98e3 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java @@ -0,0 +1,122 @@ +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ArrayListTest { + + private ArrayList arrayList; + @Before + public void init() { + arrayList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + arrayList.add(i); + } + } + + @Test + public void size() throws Exception { + Assert.assertEquals(5, arrayList.size()); + arrayList.add(6); + Assert.assertEquals(6, arrayList.size()); + + } + + @Test + public void isEmpty() throws Exception { + arrayList.clear(); + Assert.assertEquals(0, arrayList.size()); + Assert.assertTrue(arrayList.isEmpty()); + } + + @Test + public void contains() throws Exception { + Assert.assertTrue(arrayList.contains(0)); + Assert.assertTrue(arrayList.contains(4)); + Assert.assertFalse(arrayList.contains(5)); + } + + @Test + public void toArray() throws Exception { + Integer[] integers = new Integer[]{0, 1, 2, 3, 4}; + Assert.assertArrayEquals(integers, arrayList.toArray()); + } + + @Test + public void add() throws Exception { + arrayList.add(5); + Assert.assertEquals(5, arrayList.get(arrayList.size() - 1).intValue()); + arrayList.add(0, 6); + arrayList.add(3, 7); + arrayList.add(arrayList.size(), 8); + + Assert.assertEquals(9, arrayList.size()); + Assert.assertEquals(6, arrayList.get(0).intValue()); + Assert.assertEquals(8, arrayList.get(arrayList.size()-1).intValue()); + Assert.assertEquals(7, arrayList.get(3).intValue()); + } + + @Test + public void remove() throws Exception { + arrayList.remove(0); + arrayList.remove(3); + arrayList.add(5); + Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{1,2,3,5}); + + arrayList.remove(new Integer(1)); + arrayList.remove(new Integer(2)); + arrayList.remove(new Integer(5)); + arrayList.add(6); + arrayList.add(7); + + Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{3,6,7}); + + } + + + + @Test + public void get() throws Exception { + Assert.assertEquals(0, arrayList.get(0).intValue()); + Assert.assertEquals(3, arrayList.get(3).intValue()); + arrayList.add(5); + arrayList.remove(0); + Assert.assertEquals(5, arrayList.get(4).intValue()); + } + + @Test + public void set() throws Exception { + arrayList.set(0,100); + arrayList.set(arrayList.size() - 1, 50); + Assert.assertEquals(100, arrayList.get(0).intValue()); + Assert.assertEquals(50, arrayList.get(arrayList.size() - 1).intValue()); + + } + + + + + + @Test + public void indexOf() throws Exception { + Assert.assertEquals(0, arrayList.indexOf(0)); + Assert.assertEquals(1, arrayList.indexOf(1)); + } + + @Test + public void iterator() throws Exception { + Iterator iterator = arrayList.iterator(); + Assert.assertTrue(iterator.hasNext()); + Assert.assertEquals(0, iterator.next()); + Assert.assertEquals(1, iterator.next()); + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java new file mode 100644 index 0000000000..f16a7ab5ab --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java @@ -0,0 +1,94 @@ +package com.coding.basic.array; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +/** + * Created by bobi on 2017/4/4. + * at code2017 + */ +public class ArrayUtilTest { + + private static int[] arr; + + @Before + public void setUp() throws Exception { + + arr = new int[10]; + + for (int i = 0; i < arr.length; i++) { + arr[i] = i; + } + + } + + private static void arrPrint(int[] arr){ + for (int i : arr) { + System.out.print(i + " "); + } + System.out.println(); + } + + @Test + public void reverseArray() throws Exception { + ArrayUtil.reverseArray(arr); + for (int i = 0; i < arr.length; i++) { + Assert.assertEquals(9-i, arr[i]); + } + } + + @Test + public void removeZero() throws Exception { + int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; + oldArr = ArrayUtil.removeZero(oldArr); + + Assert.assertArrayEquals(new int[]{1,3,4,5,6,6,5,4,7,6,7,5}, oldArr); + + } + + @Test + public void merge() throws Exception { + int[] a1 = {3, 5, 7,8}; + int[] a2 = {4, 5, 6,7} ; + + int[] a3 = ArrayUtil.merge(a1, a2); + Assert.assertArrayEquals(new int[]{3,4,5,6,7,8}, a3); + } + + @Test + public void grow() throws Exception { + int[] a1 = {3, 5, 7,8}; + a1 = ArrayUtil.grow(a1, 3); + + Assert.assertArrayEquals(new int[]{3,5,7,8,0,0,0}, a1); + } + + @Test + public void fibonacci() throws Exception { + int[] arr = ArrayUtil.fibonacci1(100); + arrPrint(arr); + } + + @Test + public void getPrimes() throws Exception { + int[] a1 = ArrayUtil.getPrimes(100); + arrPrint(a1); + } + + @Test + public void getPerfectNumbers() throws Exception { + int[] a1 = ArrayUtil.getPerfectNumbers(10000); + arrPrint(a1); + } + + @Test + public void join() throws Exception { + int[] a1 = {3,4,5,6,7}; + String str = ArrayUtil.join(a1, "-"); + System.out.println("str = " + str); + + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java new file mode 100644 index 0000000000..f020e64828 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java @@ -0,0 +1,155 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +/** + * Created by bobi on 2017/3/31. + * at code2017 + */ +public class LinkedListTest { + + + @Before + public void init() { + linkedList = new LinkedList<>(); + for (int i = 0; i < 6; i++) { + linkedList.add(1< linkedList; + + @Test + public void remove() throws Exception { + //测试添加删除 + { + linkedList.printf(); + linkedList.remove(new Integer(1)); + linkedList.remove(new Integer(8)); + linkedList.remove(new Integer(32)); + linkedList.add(50); + linkedList.add(0, 100); + Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100, 2, 4, 16, 50}); + +// + linkedList.remove(new Integer(16)); + linkedList.add(linkedList.size() - 1, 25); + Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100,2, 4, 25, 50}); + } + + } + + + @Test + public void removeFirstHalf() throws Exception { + linkedList.removeFirstHalf(); + linkedList.removeFirstHalf(); + linkedList.printf(); + } + + @Test + public void getElements() throws Exception { + + } + + @Test + public void subtract() throws Exception { + + } + + @Test + public void removeDuplicateValues() throws Exception { + linkedList.removeFirstHalf(); + LinkedList list = new LinkedList(); + list.add(8); + list.add(16); + list.add(32); + Assert.assertArrayEquals(linkedList.toArray(), list.toArray()); + linkedList.removeFirstHalf(); + list.remove(0); + Assert.assertArrayEquals(linkedList.toArray(), list.toArray()); + + } + + @Test + public void removeByLength() throws Exception { + // 测试删除开始节点 + { + linkedList.remove(0, 2); + Assert.assertEquals(linkedList.size(), 4); + for (int i = 0; i < 3; i++) { + Assert.assertEquals(linkedList.get(i).intValue(), 1<<(i+2)); + } + } + + // 测试删除中间节点 + { + init(); + linkedList.remove(1, 2); + Assert.assertEquals(linkedList.size(), 4); + Assert.assertEquals(linkedList.get(0).intValue(), 1); + Assert.assertEquals(linkedList.get(1).intValue(), 8); + Assert.assertEquals(linkedList.get(2).intValue(), 16); + } +// + // 测试删除末尾节点 + { + init(); + linkedList.remove(4, 2); + Assert.assertEquals(linkedList.size(), 4); + Assert.assertEquals(linkedList.get(0).intValue(), 1); + Assert.assertEquals(linkedList.get(1).intValue(), 2); + Assert.assertEquals(linkedList.get(2).intValue(), 4); + Assert.assertEquals(linkedList.get(3).intValue(), 8); + } +// + // 测试删除全部 + { + init(); + linkedList.remove(0, 6); + Assert.assertEquals(linkedList.size(), 0); + } + } + + @Test + public void intersection() throws Exception { + + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java new file mode 100644 index 0000000000..cd0d8abcc8 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java @@ -0,0 +1,68 @@ +package com.coding.basic.queue; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ArrayQueueTest { + private ArrayQueue arrayQueue; + + @Before + public void init(){ + arrayQueue = new ArrayQueue<>(6); + for (int i = 0; i < 5; i++) { + arrayQueue.add(i); + } + + } + @Test + public void add() throws Exception { + Assert.assertTrue(arrayQueue.add(5)); + + + Assert.assertEquals(0, arrayQueue.peek().intValue()); + Assert.assertEquals(0, arrayQueue.poll().intValue()); + Assert.assertEquals(1, arrayQueue.poll().intValue()); + + for (int i = 0; i < 4; i++) { + arrayQueue.remove(); + } + Assert.assertTrue(arrayQueue.isEmpty()); + } + + @Test + public void offer() throws Exception { + Assert.assertTrue(arrayQueue.offer(5)); + Assert.assertFalse(arrayQueue.offer(6)); + } + + @Test + public void remove() throws Exception { + arrayQueue.remove(); + arrayQueue.remove(); + arrayQueue.remove(); + arrayQueue.remove(); + + arrayQueue.add(5); + arrayQueue.add(6); + arrayQueue.add(7); + arrayQueue.add(8); + arrayQueue.add(9); + + + Assert.assertEquals(4, arrayQueue.remove().intValue()); + Assert.assertEquals(5, arrayQueue.remove().intValue()); + Assert.assertEquals(6, arrayQueue.remove().intValue()); + Assert.assertEquals(7, arrayQueue.remove().intValue()); + Assert.assertEquals(8, arrayQueue.remove().intValue()); + Assert.assertEquals(9, arrayQueue.remove().intValue()); + } + + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..40a3013741 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java @@ -0,0 +1,45 @@ +package com.coding.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ConfigurationTest { + private Configuration config; + @Before + public void setUp() throws Exception { + config = new Configuration("struts.xml"); + } + + @After + public void tearDown() throws Exception { + + } + + + @Test + public void testGetClassName(){ + String clzName = config.getClassName("login"); + Assert.assertEquals("com.coding.litestruts.LoginAction", clzName); + clzName = config.getClassName("logout"); + Assert.assertEquals("com.coding.litestruts.LogoutAction", clzName); + + } + + @Test + public void testGetResultView(){ + String jsp = config.getResultView("login", "success"); + Assert.assertEquals("jsp/homepage.jsp", jsp); + + jsp = config.getResultView("login", "fail"); + Assert.assertEquals("jsp/showLogin.jsp", jsp); + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..d66188988b --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java @@ -0,0 +1,124 @@ +package com.coding.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ReflectionUtilTest { + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void testGetSetterMethod() throws ClassNotFoundException { + String name = "com.coding.litestruts.LoginAction"; + + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + List acctualNames = new ArrayList<>(); + for (Method method : methods) { + acctualNames.add(method.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + + } + + @Test + public void testSetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { + String name = "com.coding.litestruts.LoginAction"; + + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap<>(); + params.put("name", "test"); + params.put("password", "1234"); + + ReflectionUtil.setParameters(o, params); + + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + } + + + @Test + public void testGetGetterMethod() throws ClassNotFoundException { + String name = "com.coding.litestruts.LoginAction"; + + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + expectedNames.add("getMessage"); + + List acctualNames = new ArrayList<>(); + + for (Method method : methods) { + acctualNames.add(method.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + + } + + @Test + public void testGetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { + String name = "com.coding.litestruts.LoginAction"; + Class clz = Class.forName(name); + + LoginAction o = (LoginAction) clz.newInstance(); + o.setName("test"); + o.setPassword("123456"); + + Map params; + params = ReflectionUtil.getParamterMap(o); + + Assert.assertEquals(3, params.size()); + Assert.assertEquals(null, params.get("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + + + } + + @Test + public void testDouble(){ + double d = 6.02e23; + long i = (long) d; + System.out.println(i); + } +} \ No newline at end of file diff --git a/group04/120549547/my.txt b/group04/120549547/my.txt deleted file mode 100644 index 3da1ec26e9..0000000000 --- a/group04/120549547/my.txt +++ /dev/null @@ -1 +0,0 @@ -HelloWorld diff --git a/group04/1299310140/src/com/coderising/download/DownloadThread.java b/group04/1299310140/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..a9e0d41dfa --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,38 @@ +package com.coderising.download; + +import java.io.FileOutputStream; +import java.io.IOException; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + byte[] result; + + public DownloadThread( Connection conn, int startPos, int endPos, byte[] result){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.result = result; + + } + public void run(){ + try { + byte[] download = this.conn.read(this.startPos, this.endPos); + //synchronized(this.result){ + System.arraycopy(download, 0, this.result, this.startPos, download.length); + System.out.println(this.startPos+" "+this.endPos); + //} + FileOutputStream fos = new FileOutputStream("C:\\b.jpg"); + fos.write(this.result); + fos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/group04/1299310140/src/com/coderising/download/FileDownloader.java b/group04/1299310140/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c094717293 --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,83 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm = new ConnectionManagerImpl(); + + public FileDownloader(String _url) { + this.url = _url; + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection connOne = null; + Connection connTwo = null; + Connection connThree = null; + try { + + connOne = cm.open(this.url); + connTwo = cm.open(this.url); + connThree = cm.open(this.url); + + int length = connOne.getContentLength(); + + byte[] result = new byte[length]; + new DownloadThread(connOne,0,length/3,result).start(); + new DownloadThread(connTwo,length/3+1,length/2,result).start(); + new DownloadThread(connThree,length/2+1,length-1,result).start(); + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(connOne != null){ + connOne.close(); + } + if(connTwo != null){ + connTwo.close(); + } + if(connThree != null){ + connThree.close(); + } + } + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + + public static void main(String[] args){ + new FileDownloader("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg").execute(); + } + +} diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..52884cfd2f --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,59 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + private URLConnection urlconn; + private InputStream fis; + + public ConnectionImpl(URLConnection urlconn) { + super(); + this.urlconn = urlconn; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException{ + this.fis = this.urlconn.getURL().openStream(); + byte[] buffer = new byte[512]; + int count = 0;//某次read的字节数 + int sum = 0;//read的总字节数 + int length = endPos - startPos + 1;//当前线程需读取的字节数 + byte[] download = new byte[length]; + fis.skip(startPos); + while((count = fis.read(buffer)) != -1){ + if(sum + count >= length){ + System.arraycopy(buffer, 0, download, sum, length - sum); + sum = length; + break; + }else{ + System.arraycopy(buffer, 0, download, sum, count); + sum = sum + count; + } + } + return download; + } + + @Override + public int getContentLength() { + return this.urlconn.getContentLength(); + } + + @Override + public void close() { + if(this.fis != null){ + try { + this.fis.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + +} diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..4af847dc88 --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,31 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + try { + URL myurl = new URL("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg"); + URLConnection urlconn = myurl.openConnection(); + ConnectionImpl conn = new ConnectionImpl(urlconn); + return conn; + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + +} diff --git a/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..4b85fa7ed1 --- /dev/null +++ b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws Exception{ + //com.coderising.jvm.test.EmployeeV1 + //"com\\coderising\\jvm\\test\\EmployeeV1" + String clzFileName = this.getClassPath() + "\\" + className.replace(".", "\\") + ".class"; + //FileInputStream BufferedInputStream ByteArrayOutputStream + File file = new File(clzFileName); + + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + + int length = -1; + + while((length = bis.read(buffer)) != -1){ + bos.write(buffer,0,length); + } + + byte[] result = bos.toByteArray(); + bis.close(); + bos.close(); + + return result; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + String result = ""; + for(int i = 0;i < clzPaths.size();i++){ + result = result + clzPaths.get(i); + if(i == clzPaths.size() - 1){ + break; + } + result = result + ";"; + } + return result; + } + +} diff --git a/group04/1299310140/src/com/coding/basic/LinkedList.java b/group04/1299310140/src/com/coding/basic/LinkedList.java index 4636bbd279..3e908613db 100644 --- a/group04/1299310140/src/com/coding/basic/LinkedList.java +++ b/group04/1299310140/src/com/coding/basic/LinkedList.java @@ -208,4 +208,285 @@ public String toString(){ return result; } } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(this.size <= 1){ + return; + } + Node before = null; + Node pres = this.head; + Node after = pres.next; + while(after != null){ + pres.next = before; + before = pres; + pres = after; + after = after.next; + } + //此时pres指向最后一个节点 + pres.next = before; + this.head = pres; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + if(this.size <= 1){ + return; + } + Node pres = this.head; + Node temp = pres; + for(int i = 0;i < this.size / 2;i++){ + temp = pres; + pres = pres.next; + temp.data = null; + temp.next = null; + } + this.head = pres; + this.size = this.size - this.size / 2; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param index + * @param length + */ + public void remove(int index, int length){//若length太大,size不够,则取到末尾 + if(index < 0 || index >= this.size || length <= 0){//index小于0or大于等于size,length小于等于0,参数错误 + return; + } + if(this.size <= 0){ + return; + } + if(index == 0){ + //此时index=0&&length>0&&size>0 + Node temp = this.head; + for(int i = 0;i < length;i++){ + temp = temp.next; + if(temp == null){ + break; + } + } + this.head = temp; + if(temp == null){ + this.size = 0; + }else{ + this.size = this.size - length; + } + }else{ + //此时00&&size>0 + Node start = this.head; + for(int j = 0;j < index-1;j++){ + start = start.next; + }//start指向index-1 + + Node end = start; + for(int l = 0;l <= length;l++){ + end = end.next; + if(end == null){ + break; + } + }//end指向index+length + start.next = end; + if(end == null){ + this.size = index; + }else{ + this.size = this.size - length; + } + } + } + + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){//若listB中的index不在0~this.size-1之中,则返回-1 + if(this.size <= 0 || list == null || list.size <= 0){ + return null; + } + + int[] result = new int[list.size()]; + Node presIndex = list.head; + int index = (int)presIndex.data; + for(int i = 0;i < list.size();i++){ + if(index < 0 || index >= this.size){ + result[i] = -1; + }else{//index:0~this.size-1 + result[i] = (int)this.get(index); + } + presIndex = presIndex.next; + if(presIndex != null){ + index = (int)presIndex.data; + } + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + * @param list + */ + public void subtract(LinkedList list){//当前链表以及参数列表均递增有序,可有重复值 + if(this.size == 0 || list == null || list.size() == 0){ + return; + } + + //头节点的删除比较特殊,先不予考虑 + Node thisPres = this.head.next;//指向被删除节点 + Node thisPresBefore = this.head;//指向被删除节点的前一个节点 + Node listPres = list.head; + while(thisPres != null && listPres != null){ + if((int)thisPres.data > (int)listPres.data){ + listPres = listPres.next; + }else if((int)thisPres.data < (int)listPres.data){ + thisPresBefore = thisPresBefore.next; + thisPres = thisPres.next; + }else{//(int)thisPres.data == (int)listPres.data + thisPresBefore.next = thisPres.next; + thisPres = thisPres.next; + this.size--; + } + } + + //最后考虑头节点的删除情况 + Node first = this.head; + Node listPresTwo = list.head; + while((int)first.data > (int)listPresTwo.data){ + listPresTwo = listPresTwo.next; + } + if((int)first.data == (int)listPresTwo.data){//删除头节点 + this.head = this.head.next; + this.size--; + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(this.size <= 1){ + return; + } + + Node start = this.head; + Node end = start.next; + while(end != null){ + if((int)start.data != (int)end.data){ + start = end; + end = end.next; + }else{//start.data == end.data + while((int)start.data == (int)end.data){ + end = end.next; + if(end == null){ + break; + } + } + start.next = end; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(this.size == 0 || max - min < 2 || (int)this.head.data >= max){ + return; + } + + //this.size >= 1 && max - min >= 2 && this.head.data < max + int thisHeadData = (int)this.head.data; + if(thisHeadData > min && thisHeadData < max){ + //this.size >= 1 && max - min >= 2 && + //min < this.head.data < max + //找到新的头节点即可,this.size减小 + Node notSmallToMax = this.head.next; + int sizeDec = 1; + while(notSmallToMax != null){ + if((int)notSmallToMax.data >= max){ + break; + } + notSmallToMax = notSmallToMax.next; + sizeDec++; + } + this.head = notSmallToMax; + this.size = this.size - sizeDec; + }else{ + //this.size >= 1 && max - min >= 2 && + //this.head.data <= min + Node startBefore = this.head;//第一个>min节点的前一个节点 + Node start = startBefore.next;//第一个>min的节点 + while(start != null){ + if((int)start.data > min){ + break; + } + startBefore = start; + start = start.next; + } + if(start == null || (int)start.data >= max){ + //链表中不存在满足删除条件的元素 + return; + } + + //至少有一个元素需要被删除 + int sizeDec = 1; + Node end = start;//最后一个= max){ + break; + } + end = endAfter; + endAfter = endAfter.next; + sizeDec++; + } + startBefore.next = endAfter; + this.size = this.size - sizeDec; + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(list == null || list.size() == 0){ + return new LinkedList(); + } + if(this.size == 0){ + return new LinkedList(); + } + LinkedList result = new LinkedList(); + Node thisPres = this.head; + Node listPres = list.head; + while(thisPres != null && listPres != null){ + if((int)thisPres.data < (int)listPres.data){ + thisPres = thisPres.next; + }else if((int)thisPres.data > (int)listPres.data){ + listPres = listPres.next; + }else{ + //(int)thisPres.data == (int)listPres.data + result.add(thisPres.data); + thisPres = thisPres.next; + listPres = listPres.next; + } + } + return result; + } } diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..8a39813de0 --- /dev/null +++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,136 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + + } + + private int capacity; + private int size = 0; + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + removeElement(pageNum); + addFirst(pageNum); + if(this.size > this.capacity){ + removeLast(); + } + } + + //删除链表的尾节点 + private void removeLast(){ + if(this.size == 0){ + return; + } + if(this.size == 1){ + this.first = null; + this.last = null; + this.size--; + } + Node curr = this.last; + this.last = curr.prev; + this.last.next = null; + curr.prev = null; + this.size--; + } + + //根据参数删除双向链表中的某个节点 + private void removeElement(int pageNum){ + if(this.size == 0){ + return; + } + Node curr = this.first; + while(curr.pageNum != pageNum){ + if(curr.next == null){ + break; + } + curr = curr.next; + } + //此时curr指向被删除节点or链表最后一个节点 + if(curr.pageNum == pageNum){ + if(this.first == this.last){//size为1,且该节点需要被删除 + this.first = null; + this.last = null; + this.size--; + return; + } + if(curr == this.first){//删除头节点 + this.first = curr.next; + this.first.prev = null; + curr.next = null; + this.size--; + return; + } + if(curr == this.last){//删除尾节点 + this.last = curr.prev; + this.last.next = null; + curr.prev = null; + this.size--; + return; + } + + //删除中间节点 + //此时size至少为3 + curr.next.prev = curr.prev; + curr.prev.next = curr.next; + curr.prev = null; + curr.next = null; + this.size--; + } + } + + //向双向链表的头部添加节点 + private void addFirst(int pageNum){ + Node curr = new Node(pageNum); + if(this.size == 0){ + this.first = curr; + this.last = curr; + this.size++; + }else{ + curr.next = this.first; + this.first.prev = curr; + this.first = curr; + this.size++; + } + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..3e88027af5 --- /dev/null +++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,73 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; +import org.junit.Test; + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(7); + frame.access(0); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + + LRUPageFrame frameFive = new LRUPageFrame(5); + frameFive.access(7);//7 + frameFive.access(7);//7 + frameFive.access(0);//0 7 + frameFive.access(7);//7 0 + frameFive.access(0);//0 7 + frameFive.access(1);//1 0 7 + Assert.assertEquals("1,0,7", frameFive.toString()); + frameFive.access(2);//2 1 0 7 + Assert.assertEquals("2,1,0,7", frameFive.toString()); + frameFive.access(0);//0 2 1 7 + Assert.assertEquals("0,2,1,7", frameFive.toString()); + frameFive.access(0);//0 2 1 7 + Assert.assertEquals("0,2,1,7", frameFive.toString()); + frameFive.access(3);//3 0 2 1 7 + Assert.assertEquals("3,0,2,1,7", frameFive.toString()); + frameFive.access(0);//0 3 2 1 7 + Assert.assertEquals("0,3,2,1,7", frameFive.toString()); + frameFive.access(4);//4 0 3 2 1 + Assert.assertEquals("4,0,3,2,1", frameFive.toString()); + } + +// @Test +// public void testAddFirst(){ +// LRUPageFrame frame = new LRUPageFrame(3); +// frame.addFirst(1); +// frame.addFirst(2); +// Assert.assertEquals("2,1", frame.toString()); +// frame.addFirst(3); +// Assert.assertEquals("3,2,1", frame.toString()); +// frame.addFirst(4); +// Assert.assertEquals("4,3,2,1", frame.toString()); +// frame.removeElement(3); +// Assert.assertEquals("4,2,1", frame.toString()); +// frame.removeElement(1); +// Assert.assertEquals("4,2", frame.toString()); +// frame.removeElement(4); +// Assert.assertEquals("2", frame.toString()); +// frame.removeElement(2); +// Assert.assertEquals("", frame.toString()); +// } + +} diff --git a/group04/1796244932/learn01/1.png b/group04/1796244932/learn01/1.png new file mode 100644 index 0000000000000000000000000000000000000000..a25be7d057e9083652fcd595edf131048107baf3 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^3xU{;gAGV75%|&rq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c747zPaSW-r_2!bJAOi!(VS@wvpDQNMcX3)jJ7vL3l>;p^ m0+@U{I8_H5W5HWi2?oA>%$@Jfdom4j 1.6 + + + + + org.jdom + jdom + 2.0.2 + + + junit junit - 4.11 - test + 4.12 - - org.junit.jupiter - junit-jupiter-api - RELEASE - + + + + io.netty + netty + 4.0.0.Alpha8 + + diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java index 60254997aa..a425f54e81 100644 --- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java @@ -1,6 +1,13 @@ package com.dudy.learn01.base; +import java.util.LinkedList; + +/** + * 单链表: + * 因为没有尾节点 + * 存放时 add 1 2 3 4 实际是 4 3 2 1 + */ public class MyLinkedList implements MyList { private int size = 0; @@ -24,6 +31,7 @@ public void add(int index, Object o) { } private Node getCurrentNode(int index) {// 获取当前节点 + checkRange(index); Node current = head; for(int i = 0; i< size-index -1; i++){ current = current.next; @@ -56,7 +64,7 @@ public Object remove(int index) { return node.data; } - public int size() { + public int size() { return size; } @@ -108,6 +116,7 @@ public Object next() { } } + private static class Node { Object data; Node next; @@ -118,15 +127,107 @@ public Node(Object data) { } } - - private void displayLink() {// 自己调试使用 - Node current = head; - while(current != null){ - System.out.print(current.data); - current = current.next; + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + if(head == null || head.next == null){ + return ; + } + + Node current = head; // 当前节点 我的头节点是有数据的 + + while (current.next != null){ + Node p = current.next; // 当前节点的下一个 + current.next = p.next; // 当前节点的next -> current.next.next (p.next) + p.next = head; // current.next(p) -> head.next (插入到 head 和 第一个数据之间) + head = p; } - System.out.println(""); } - + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + int base = size; + Node currentNode = getCurrentNode(base / 2); + currentNode = null; + size = size - base/2; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + + Node preNode = getCurrentNode(size - i -1); + Node nextNode = getCurrentNode(size - i - length-1); + nextNode.next = preNode; + size = size -length; + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param src + */ + public Object[] getElements(int[] src){ + Object des[] = new Object[src.length]; + + for (int i = 0; i < src.length; i++){ + des[i] = getCurrentNode(size - 1 - i).data; + } + + return des; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + return null; + } } \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java new file mode 100644 index 0000000000..84e9bd5d2c --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java @@ -0,0 +1,40 @@ +package com.dudy.learn01.designPattern.singleton; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by dudy on 2017/3/6. + */ +public enum EnumSingleton { + + SINGLETON; + private EnumSingleton(){} + + + public static void main(String[] args) { + + ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 6000 * 10, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue(5)); + + + for (int i = 0; i< 16; i++){ + executor.execute(new EnumSingletonTest()); + } + + executor.shutdown(); + + + } +} + + +class EnumSingletonTest implements Runnable{ + + @Override + public void run() { + EnumSingleton singleton = EnumSingleton.SINGLETON; + System.out.println(singleton.hashCode()); + } +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java new file mode 100644 index 0000000000..8de831c354 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java @@ -0,0 +1,66 @@ +package com.dudy.learn01.designPattern.singleton; + +import java.io.Serializable; +import java.util.concurrent.*; + +/** + * Created by dudy on 2017/3/6. + * 双检索 方式 + * jdk1.5 以后 其实是线程安全的。 + * 序列化会 破坏 单利 + * + */ +public class SingletonDemo1 implements Serializable{ + + private static volatile SingletonDemo1 singleton = null; // 加 volatile 是为了 可见性,另一个就是 避免重排序 + + private SingletonDemo1(){} + + public static SingletonDemo1 getIntance(){ + + if (singleton == null){// 第一个避免 在 synchronized 中 一直排队 + synchronized (SingletonDemo1.class){ + + if (singleton == null){// 如果对象为空,才被创建 + singleton = new SingletonDemo1(); + } + + } + } + + return singleton; + } + + + /** + * 解决 反序列化的问题 + * @return + */ + private Object readResolve() { + return singleton; + } + + public static void main(String[] args) { + + ExecutorService threadPool = Executors.newFixedThreadPool(10); + + for (int i= 0 ;i < 5; i++){ + threadPool.execute(new TestRunable()); + } + + threadPool.shutdown(); + + //new ThreadPoolExecutor(10,20,1000*2,new BlockingQueue(),) + + + } + +} + + class TestRunable implements Runnable{ + + public void run() { + SingletonDemo1 intance = SingletonDemo1.getIntance(); + System.out.println(intance.hashCode()); + } + } diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java new file mode 100644 index 0000000000..d8b484cd15 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java @@ -0,0 +1,63 @@ +package com.dudy.learn01.designPattern.singleton; + +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by dudy on 2017/3/6. + * + * 静态内部类方式 实现 + * + * 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程, + * 它跟饿汉式不同的是(很细微的差别):饿汉式是只要Singleton类被装载了, + * 那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了, + * instance不一定被初始化。因为SingletonHolder类没有被主动使用, + * 只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类, + * 从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载, + * 另外一方面,我不希望在Singleton类加载时就实例化, + * 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载, + * 那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比饿汉式更加合理 + * + */ +public class StaticClassInnerSingleton { + + // 构造器 私有化 + private StaticClassInnerSingleton(){} + + private static class SingletonHolder{ + private static final StaticClassInnerSingleton INSTANCE = new StaticClassInnerSingleton(); + } + + + public static StaticClassInnerSingleton getInstance(){ + return SingletonHolder.INSTANCE; + } + + + public static void main(String[] args) { + + + ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, + 6000 * 10, TimeUnit.MILLISECONDS, + new LinkedBlockingDeque()); + + for (int i= 0; i<20; i++){ + pool.execute(new StaicSingletonTest()); + //System.out.println(StaticClassInnerSingleton.getInstance().hashCode()); + } + + pool.shutdown(); + } + + + +} + +class StaicSingletonTest implements Runnable{ + + public void run() { + StaticClassInnerSingleton intance = StaticClassInnerSingleton.getInstance(); + System.out.println(intance.hashCode()); + } +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java new file mode 100644 index 0000000000..97ca01e13b --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java @@ -0,0 +1,59 @@ +package com.dudy.learn01.download; + +import com.dudy.learn01.download.api.Connection; + +import java.io.*; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; + +public class DownloadThread extends Thread{ + + private Connection conn; + private int startPos; + private int endPos; + private RandomAccessFile raf; + //private CyclicBarrier cb; + private CountDownLatch downLatch; + + + public DownloadThread(Connection conn, int startPos, int endPos, + /*CyclicBarrier cb*/ + CountDownLatch downLatch){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; +// this.cb = cb; + this.downLatch = downLatch; + } + public void run(){ + try { + byte[] read = conn.read(startPos, endPos); + + System.out.println("read length: -> "+read.length); + //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的 + raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw"); + //将写文件的指针指向下载的起始点 + raf.seek(startPos); + raf.write(read, 0, read.length); + + downLatch.countDown(); +// cb.await(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (raf != null){ + raf.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + if (conn != null){ + conn.close(); + } + + } + } +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java new file mode 100644 index 0000000000..eee5825b84 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java @@ -0,0 +1,93 @@ +package com.dudy.learn01.download; + +import com.dudy.learn01.download.api.Connection; +import com.dudy.learn01.download.api.ConnectionManager; +import com.dudy.learn01.download.api.DownloadListener; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; + +public class FileDownloader { + + private static final int THREAD_NUM = 3; + + private String url; + + private DownloadListener listener; + + private ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() throws IOException { + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + //CyclicBarrier cb = new CyclicBarrier(THREAD_NUM); + CountDownLatch downLatch = new CountDownLatch(THREAD_NUM); + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + for (int i = 0;i < THREAD_NUM; i++){ + + int start=i*length/THREAD_NUM; + int end = (i+1)*length/THREAD_NUM-1; + if(i==THREAD_NUM-1) + { + end =length; + } + + new DownloadThread(cm.open(url),start,end,downLatch).start(); + } + + //cb.await(); + downLatch.await(); + getListener().notifyFinished(); + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java new file mode 100644 index 0000000000..513c0004e9 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.dudy.learn01.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java new file mode 100644 index 0000000000..71af9bf06d --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.dudy.learn01.download.api; + +public class ConnectionException extends Exception { + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java new file mode 100644 index 0000000000..5f4777f6e0 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java @@ -0,0 +1,13 @@ +package com.dudy.learn01.download.api; + +import java.io.IOException; +import java.net.MalformedURLException; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException, IOException; +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java new file mode 100644 index 0000000000..fa3b5bead0 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.dudy.learn01.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..5eb6b45d41 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java @@ -0,0 +1,89 @@ +package com.dudy.learn01.download.impl; + +import com.dudy.learn01.download.api.Connection; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ConnectionImpl implements Connection { + + + private HttpURLConnection connection; + + public ConnectionImpl(String url) { + try { + this.connection = (HttpURLConnection) new URL(url).openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream in = connection.getInputStream(); + byte buffer[] = new byte[endPos-startPos+1]; + byte result[] = new byte[endPos-startPos+1]; + int count = 0; // 记录已经读取的数据 + int length = -1 ; + + while ((length = in.read(buffer)) > 0){ + System.arraycopy(buffer,0,result,count,length); + count += length; + } + return result; + } + + @Override + public int getContentLength() { + return connection.getContentLength(); + } + + @Override + public void close() { + if (connection != null){ + connection.disconnect(); + } + } + + public static void main(String[] args) throws Exception{ + //String PATH = "http://demo2.yun.myuclass.com/upload/demo2.yun.myuclass.com/winshare/pagelogo/250617391.png"; + String PATH = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png"; + + URL url = new URL(PATH); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + //conn.setConnectTimeout(5000); + //conn.setRequestMethod("GET"); + //设置头部的参数,表示请求服务器资源的某一部分 + //conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + //设置了上面的头信息后,响应码为206代表请求资源成功,而不再是200 + int code = conn.getResponseCode(); + System.out.println(conn.getContentLength()); + if(code == 200){ + + InputStream is = conn.getInputStream(); + int hasRead = 0; + byte[] buf = new byte[conn.getContentLength()]; + System.out.println(buf.length); + //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的 + RandomAccessFile raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw"); + //将写文件的指针指向下载的起始点 + raf.seek(0); + + while((hasRead = is.read(buf,0,conn.getContentLength())) > 0) { + System.out.println("hasRead = " + hasRead); + raf.write(buf, 0, hasRead); + } + is.close(); + raf.close(); + conn.disconnect(); + } + } + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..809f98d91b --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,25 @@ +package com.dudy.learn01.download.impl; + +import com.dudy.learn01.download.api.Connection; +import com.dudy.learn01.download.api.ConnectionException; +import com.dudy.learn01.download.api.ConnectionManager; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + + private Connection connection = null; + + @Override + public Connection open(String url) throws ConnectionException, IOException { + + connection = new ConnectionImpl(url); + + return connection; + } + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java new file mode 100644 index 0000000000..e4239ae521 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java @@ -0,0 +1,64 @@ +package com.dudy.learn01.juc; + +/** + * Created by dudy on 2017/3/9. + * + * 4. ThreadLocal 这个类实现原理和用途,在哪里用到了 + * 每个ThreadLocal可以放一个线程级别的变量,但是它本身可以被多个线程共享变量,而且又可以达到线程安全的目的,且绝对线程安全 + * spring的事物管理Session, 连接池管理 Connection + * https://my.oschina.net/huangyong/blog/159725 + * 数据库事物的前提是: 必须是同一个连接 + */ +public class ThreadLocalTest { + + static class Resource{ + public static final ThreadLocal RESOURCE1 = new ThreadLocal(); + public static final ThreadLocal RESOURCE2 = new ThreadLocal(); + } + + static class A { + public void setOne(String str){ + Resource.RESOURCE1.set(str); + } + + public void setTwo(String str){ + Resource.RESOURCE2.set(str); + } + } + + static class B { + public void display(){ + System.out.println(Resource.RESOURCE1.get() + +":" + Resource.RESOURCE2.get()); + } + } + + public static void main(String[] args) { + + final A a = new A(); + final B b = new B(); + + for (int i = 0; i< 5 ;i++){ + + final String resource1 = "Thread_" + i; + final String resource2 = "value " + i; + + new Thread(new Runnable() { + @Override + public void run() { + try { + a.setOne(resource1); + a.setTwo(resource2); + b.display(); + }finally { + Resource.RESOURCE2.remove(); + Resource.RESOURCE1.remove(); + } + } + }).start(); + } + + } + + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java index bbe8c108ca..c08ae7ae49 100644 --- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java @@ -46,6 +46,7 @@ public static View runAction(String actionName, Map parameters) { for (Map.Entry entry : parameters.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); // 这里 只能传递object吧 + //actionClass.gett Method method = actionClass.getDeclaredMethod(methodNameconversion(entry.getKey()), String.class); method.setAccessible(true); method.invoke(base,entry.getValue()); diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java new file mode 100644 index 0000000000..fb2fb74fad --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java @@ -0,0 +1,113 @@ +package com.dudy.learn01.litestruts.format; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; + +public class Configuration { + + Map actions = new HashMap<>(); + + public Configuration(String fileName) { + + String packageName = this.getClass().getPackage().getName(); + + packageName = packageName.replace('.', '/'); + + InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + private void parseXML(InputStream is){ + + SAXBuilder builder = new SAXBuilder(); + + try { + + Document doc = builder.build(is); + + Element root = doc.getRootElement(); + + for(Element actionElement : root.getChildren("action")){ + + String actionName = actionElement.getAttributeValue("name"); + String clzName = actionElement.getAttributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, clzName); + + for(Element resultElement : actionElement.getChildren("result")){ + + String resultName = resultElement.getAttributeValue("name"); + String viewName = resultElement.getText().trim(); + + ac.addViewResult(resultName, viewName); + + } + + this.actions.put(actionName, ac); + } + + + } catch (JDOMException e) { + throw new ConfigurationException(e); + + } catch (IOException e) { + throw new ConfigurationException(e); + + } + + + } + + public String getClassName(String action) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getClassName(); + } + + public String getResultView(String action, String resultName) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getViewName(resultName); + } + + private static class ActionConfig{ + + String name; + String clzName; + Map viewResult = new HashMap<>(); + + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + public String getClassName(){ + return clzName; + } + public void addViewResult(String name, String viewName){ + viewResult.put(name, viewName); + } + public String getViewName(String resultName){ + return viewResult.get(resultName); + } + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java new file mode 100644 index 0000000000..a9d3048491 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.dudy.learn01.litestruts.format; + +import java.io.IOException; + +import org.jdom2.JDOMException; + +public class ConfigurationException extends RuntimeException { + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java new file mode 100644 index 0000000000..fc553fc0fc --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.dudy.learn01.litestruts.format; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ConfigurationTest { + + + Configuration cfg = new Configuration("struts.xml"); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetClassName() { + + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName); + + + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName); + } + + @Test + public void testGetResultView(){ + String jsp = cfg.getResultView("login","success"); + Assert.assertEquals("/jsp/homepage.jsp", jsp); + + jsp = cfg.getResultView("login","fail"); + Assert.assertEquals("/jsp/showLogin.jsp", jsp); + + jsp = cfg.getResultView("logout","success"); + Assert.assertEquals("/jsp/welcome.jsp", jsp); + + jsp = cfg.getResultView("logout","error"); + Assert.assertEquals("/jsp/error.jsp", jsp); + + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java new file mode 100644 index 0000000000..3b49e8dec3 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java @@ -0,0 +1,39 @@ +package com.dudy.learn01.litestruts.format; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java new file mode 100644 index 0000000000..a85157ace5 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.dudy.learn01.litestruts.format; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + + return getMethods(clz,"set"); + + } + + public static void setParameters(Object o, Map params) { + + List methods = getSetterMethods(o.getClass()); + + for(String name : params.keySet() ){ + + String methodName = "set" + name; + + for(Method m: methods){ + + if(m.getName().equalsIgnoreCase(methodName)){ + try { + m.invoke(o, params.get(name)); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz,"get"); + } + + private static List getMethods(Class clz, String startWithName){ + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith(startWithName)){ + + methods.add(m); + + } + + } + + return methods; + } + + public static Map getParamterMap(Object o) { + + Map params = new HashMap<>(); + + List methods = getGetterMethods(o.getClass()); + + for(Method m : methods){ + + String methodName = m.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); + try { + Object value = m.invoke(o); + params.put(name, value); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + + e.printStackTrace(); + } + } + + return params; + } + + ////////////////////////Backup /////////////////////////////////// + + public static List getGetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("get")){ + + methods.add(m); + + } + + } + + return methods; + } + + public static List getSetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("set")){ + + methods.add(m); + + } + + } + + return methods; + + } + + + + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java new file mode 100644 index 0000000000..a2d4ab945a --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java @@ -0,0 +1,113 @@ +package com.dudy.learn01.litestruts.format; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ReflectionUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetSetterMethod() throws Exception { + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception{ + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + ReflectionUtil.setParameters(o,params); + + + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + f = clz.getDeclaredField("password"); + f.setAccessible(true); + Assert.assertEquals("1234", f.get(o)); + } + @Test + public void testGetGetterMethod() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getMessage"); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testGetParamters() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + LoginAction action = (LoginAction)clz.newInstance(); + action.setName("test"); + action.setPassword("123456"); + + + + + Map params = ReflectionUtil.getParamterMap(action); + + Assert.assertEquals(3, params.size()); + + Assert.assertEquals(null, params.get("messaage") ); + Assert.assertEquals("test", params.get("name") ); + Assert.assertEquals("123456", params.get("password") ); + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java new file mode 100644 index 0000000000..3615fae5f2 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java @@ -0,0 +1,68 @@ +package com.dudy.learn01.litestruts.format; + +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + private final static Configuration cfg = new Configuration("struts.xml"); + + public static View runAction(String actionName, Map parameters) { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + + String clzName = cfg.getClassName(actionName); + + if(clzName == null){ + return null; + } + + try { + + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + + ReflectionUtil.setParameters(action, parameters); + + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String)m.invoke(action); + + Map params = ReflectionUtil.getParamterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + + + + } catch (Exception e) { + + e.printStackTrace(); + } + return null; + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java new file mode 100644 index 0000000000..0053461c01 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java @@ -0,0 +1,43 @@ +package com.dudy.learn01.litestruts.format; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java new file mode 100644 index 0000000000..07278f2519 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java @@ -0,0 +1,23 @@ +package com.dudy.learn01.litestruts.format; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java new file mode 100644 index 0000000000..2763af6d55 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java @@ -0,0 +1,104 @@ +package com.dudy.learn01.utils; + +import java.util.Arrays; + +/** + * Created by dudy on 2017/3/6. + * 练习数组的各种排序 + * 参考:http://wiki.jikexueyuan.com/project/java-special-topic/sort.html + * http://www.cnblogs.com/liuling/p/2013-7-24-01.html + * + * 内排序有可以分为以下几类: + +   (1)、插入排序:直接插入排序、二分法插入排序、希尔排序。 + +   (2)、选择排序:简单选择排序、堆排序。 + +   (3)、交换排序:冒泡排序、快速排序。 + +   (4)、归并排序 + +   (5)、基数排序 + * + */ +public class ArraySortDemo { + + + /** + * 二分法查找 插入 + * 和 直接插入排序不同的是: 查找 要插入的位置的方式不同 + * 二分法前提是有序的** + */ + public static void dichotomySort(int src[]){ + + for (int i = 0; i< src.length ; i++){ + int temp = src[i]; + int right = i - 1; + int mid = 0; + int left = 0; + while (left <= right){ + mid = (left + right)/2; + if (temp > src[mid]){ + left = mid + 1; + } else { + right = mid - 1; + } + } + + for (int j = i-1;j>=left ; j--){ + src[j+1] = src[j]; + } + + System.out.println("left = " + left +" ,mid = " + mid + " ,right = " + right); + src[left] = temp; + + } + } + + + + + /** + * 直接插入排序 + * 思想:假定前边是有序地部分, 后边无序的插入到前边部分 + * 可以转变思想: 从后往前遍历, 将有序部分大于当前的值 往后移 + * @param src + */ + public static void directInsertSort(int[] src){ + + for (int i = 1;i < src.length ; i++){ + // 待插入的元素 + int temp = src[i]; + int j; + for ( j = i -1; j >= 0; j--){ + // 大于 temp的往后移动 + if (src[j] > temp){ + src[j+1] = src[j]; + } else { + break; + } + }// 此时遍历完 j+1 为要插入的位置 + src[j+1] = temp; + } + + } + + + + public static void main(String[] args) { + int a[] = new int[]{46,89,14,44,90,32,25,67,23}; + // 14,23,25,32,44,46,67,89,90 + //Arrays.sort(a); + + + //directInsertSort(a); + + dichotomySort(a); + + for (int i = 0; i< a.length ; i++){ + System.out.print(a[i] + ","); + } + + } + +} diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java index c6ebb096ec..cce7a1c163 100644 --- a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java +++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java @@ -2,10 +2,69 @@ import java.util.LinkedList; +import org.junit.After; +import org.junit.Before; import org.junit.Test; public class MyLinkedListTest { + MyLinkedList list = new MyLinkedList(); + + @Before + public void init(){ + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + } + + @After + public void after(){ + for(MyIterator it = list.iterator(); it.hasNext();){ + System.out.print(it.next() + " "); + } + } + + @Test + public void reverse() throws Exception { + list.reverse(); + } + + @Test + public void removeFirstHalf() throws Exception { + list.removeFirstHalf(); + } + + @Test + public void remove() throws Exception { + list.remove(0,2); + } + + @Test + public void getElements() throws Exception { + + } + + @Test + public void subtract() throws Exception { + + } + + @Test + public void removeDuplicateValues() throws Exception { + + } + + @Test + public void removeRange() throws Exception { + + } + + @Test + public void intersection() throws Exception { + + } @Test diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java new file mode 100644 index 0000000000..fc427e2171 --- /dev/null +++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java @@ -0,0 +1,53 @@ +package com.dudy.learn01.download; + +import com.dudy.learn01.download.api.ConnectionManager; +import com.dudy.learn01.download.api.DownloadListener; +import com.dudy.learn01.download.impl.ConnectionManagerImpl; +import org.junit.Test; + + +import java.io.IOException; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + + + + @Test + public void testDownload() throws IOException { + + //String url = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png"; + String url = "http://img.lanrentuku.com/img/allimg/1606/14665573271238.jpg"; + FileDownloader downloader = new FileDownloader(url); + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} \ No newline at end of file diff --git a/group04/349184132/Study/.classpath b/group04/349184132/Study/.classpath deleted file mode 100644 index 2a9fa78d5e..0000000000 --- a/group04/349184132/Study/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs b/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index a698e59674..0000000000 --- a/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -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/group04/349184132/Study/bin/com/second/struts.xml b/group04/349184132/Study/bin/com/second/struts.xml deleted file mode 100644 index 554dbbe227..0000000000 --- a/group04/349184132/Study/bin/com/second/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group04/349184132/Study/bin/com/test/student2.xml b/group04/349184132/Study/bin/com/test/student2.xml deleted file mode 100644 index e21862ec75..0000000000 --- a/group04/349184132/Study/bin/com/test/student2.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - hello text - world text - diff --git a/group04/349184132/Study/bin/com/test/students.xml b/group04/349184132/Study/bin/com/test/students.xml deleted file mode 100644 index 0a503c9f6c..0000000000 --- a/group04/349184132/Study/bin/com/test/students.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - hello Text1 - hello Text2 - hello Text3 - world text1 - world text2 - world text3 - \ No newline at end of file diff --git a/group04/349184132/Study/src/com/coderising/download/DownloadThread.java b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..2b806a7f44 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,49 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread { + Connection conn; + int startPos; + int endPos; + int threadId = 0; + CyclicBarrier barrier; + + public DownloadThread(CyclicBarrier barrier, Connection conn, int threadId, + int startPos, int endPos) { + this.barrier = barrier; + this.conn = conn; + this.threadId = threadId; + this.startPos = startPos; + this.endPos = endPos; + } + + public void run() { + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile("yunpan.exe", "rwd"); + + raf.seek(startPos); + + byte[] buffer = conn.read(startPos, endPos); + + raf.write(buffer, 0, buffer.length); + raf.close(); + barrier.await(); + System.out.println("threadId" + threadId +"download success !"); + + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + + } +} diff --git a/group04/349184132/Study/src/com/coderising/download/FileDownloader.java b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..281dafde96 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,112 @@ +package com.coderising.download; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.net.URL; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +public class FileDownloader { + + boolean isFinished = false; + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + private static final int THREAD_NUM = 3; + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() { + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, + // endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, + // 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + + CyclicBarrier barrier = new CyclicBarrier(THREAD_NUM,new Runnable(){ + + @Override + public void run() { + listener.notifyFinished(); + } + + }); + + Connection conn = null; + try { + conn = cm.open(url); + + int length = conn.getContentLength(); + System.out.println("----文件总长度---- :" + length); + RandomAccessFile raf = new RandomAccessFile("yunpan.exe","rwd"); + + raf.setLength(length); + + int block = length / THREAD_NUM; + + for(int threadId = 0; threadId < THREAD_NUM; threadId++){ + int startPos = (threadId) * block; + int endPos = (threadId + 1 ) * block -1; + if(threadId-1 == THREAD_NUM){ + endPos = length; + } + System.out.println("---threadId--- :" + threadId + + "---startIndex---" + startPos + + "---endIndex---" + endPos); + //开启 线程 + URL u = new URL(url); + new DownloadThread(barrier,cm.open(url),threadId,startPos,endPos).start(); + } + + + } catch (ConnectionException e) { + + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally{ + if(conn!=null){ + conn.close(); + } + } + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return this.listener; + } + + +} diff --git a/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..604712d2a9 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,58 @@ +package com.coderising.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://down.360safe.com/yunpan/360wangpan_setup.exe"; + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + +// 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/Connection.java b/group04/349184132/Study/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1599be1296 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(String string) { + // TODO 自动生成的构造函数存根 + } + + +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..3ad903146b --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,52 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + private HttpURLConnection conn ; + public ConnectionImpl(HttpURLConnection conn) { + this.conn = conn; + } + @Override + public byte[] read(int startPos, int endPos) throws IOException { + conn.setRequestMethod("GET"); + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + conn.setConnectTimeout(5000); + + InputStream is = conn.getInputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int length = 0; + byte[] buffer = new byte[1024]; + while(-1 != ( length = is.read(buffer))){ + bos.write(buffer,0,length); + } + bos.flush(); + is.close(); + bos.close(); + + + return bos.toByteArray(); + } + + @Override + public int getContentLength() { + + return conn.getContentLength(); + } + + @Override + public void close() { + if(conn!=null){ + conn = null; + } + } + +} diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..9132787cf8 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,37 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + @Override + public Connection open(String url) throws ConnectionException { + + URL u; + HttpURLConnection hc ; + try { + u = new URL(url); + hc = (HttpURLConnection) u.openConnection(); + Connection conn = new ConnectionImpl(hc);; + return conn; + } catch (MalformedURLException e) { + e.printStackTrace(); + + } catch (IOException e) { + e.printStackTrace(); + } + return null; + + + + + + } + +} diff --git a/group04/349184132/Study/src/com/linked/Iterator.java b/group04/349184132/Study/src/com/linked/Iterator.java new file mode 100644 index 0000000000..b2397b9aa7 --- /dev/null +++ b/group04/349184132/Study/src/com/linked/Iterator.java @@ -0,0 +1,7 @@ +package com.linked; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group04/349184132/Study/src/com/linked/LinkedList.java b/group04/349184132/Study/src/com/linked/LinkedList.java new file mode 100644 index 0000000000..44aba236b4 --- /dev/null +++ b/group04/349184132/Study/src/com/linked/LinkedList.java @@ -0,0 +1,388 @@ +package com.linked; + +import java.util.Objects; + + + +public class LinkedList implements List { + + private Node head; + + private int size = 0; + + public LinkedList(){ + this.head = new Node(null,null); + } + + public boolean add(T o){ + + if(head.next == null){ + Node element = new Node(o,null); + head.next = element; + size++; + return true; + } + + Node current = head.next; + while(current != null){ + if(current.next==null){ + Node element = new Node(o,null); + current.next = element; + size++; + return true; + } + current = current.next; + } + + return false; + } + + + private void rangeCheck(int index) { + if (index < -1 || index > size - 1) + throw new IndexOutOfBoundsException(" index "); + } + public boolean add(int index , T o){ + rangeCheck(index); + + Node node = getNode(index); + Node pre = getNode(index-1); + Node newNode = new Node(o,node); + pre.next = newNode; + size++; + return true; + } + + + private Node getNode(int index){ + rangeCheck(index); + Node current = head.next; + int count = 0; + while(current!=null){ + if(count==index){ + return current; + } + count++; + current = current.next; + } + return null; + } + + public T get(int index){ + Node node = getNode(index); + return (T)node.data; + } + public T remove(int index){ + rangeCheck(index); + + Node pre = getNode(index-1); + Node cur = getNode(index); + Node next = cur.next; + pre.next = next; + cur.next = null; + size--; + return (T)cur.data; + } + + + public T remove(T o) { + int index = 0; + for (Node x = head.next; x != null; x = x.next) { + if (Objects.deepEquals(x.data, o)) { + return remove(index); + } + index++; + } + size--; + + return null; + } + + @Override + public T set(int index, T element) { + Node node = getNode(index); + node.data = element; + + return (T)node.data; + } + + @Override + public boolean contains(Object o) { + + return indexOf(o)!=-1; + } + + @Override + public int indexOf(Object o) { + int index = 0; + + for (Node x = head.next; x != null; x = x.next) { + if (Objects.deepEquals(x.data, o)) + return index; + index++; + } + return -1; + } + + @Override + public Object[] toArray() { + Object[] result = new Object[size]; + int i = 0; + for(Node x = head.next; x != null; x = x.next){ + result[i++] = x.data; + } + return null; + } + + @Override + public void clear() { + for(Node cur = head.next;cur!=null;cur = cur.next){ + Node x = cur; + x.data = null; + x.next = null; + } + head = null; + size = 0; + } + + + public int size(){ + return size; + } + public boolean isEmpty() { + return size == 0; + } + public void addFirst(Object o){ + Node newFirst = new Node(o,null); + Node oldFirst = head.next; + head.next = newFirst; + newFirst.next = oldFirst; + size++; + } + public void addLast(Object o){ + Node last = getNode(size-1); + Node newLast = new Node(o,null); + last.next = newLast; + size++; + } + public T removeFirst(){ + Node oldFirst = head.next; + Node nextNode = oldFirst.next; + head.next = nextNode; + size--; + return (T)oldFirst; + } + public T removeLast(){ + Node x = getNode(size-2);//倒数第二个结点 + Node last = x.next; + x.next = null; + size--; + return (T)last; + } + public Iterator iterator(){ + return new LinkedListIterator(); + } + + private class LinkedListIterator implements Iterator { + int pos = 0; + + @Override + public boolean hasNext() { + return pos < size; + } + + @Override + public Object next() { + if (pos > size) + throw new IllegalArgumentException(); + return get(pos++); + } + } + + + + private static class Node{ + Object data; + Node next; + private Node(Object data, Node next) { + this.data = data; + this.next = next; + + } + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public Node reverseFor(Node head){ + if(head==null){ + return null; + } + Node pre = null; + Node curr = head; + Node next = head.next; + while(curr.next!=null){ + + head.next = pre; + pre = curr; + curr = curr.next; + next = next.next; + head = curr; + } + pre = null; + curr = null; + return head; + } + /** + * 递归写法 + * @param node + * @return + */ + public Node reverseRecursion(Node current){ + if(current == null || current.next == null){ + return current; + } + Node nextNode = current.next; + current = null; + Node reverseNode = reverseRecursion(current.next); + nextNode.next = current; + + + return reverseNode; + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int delectLength = size/2; + for(int i=0;isize-length){ + throw new IllegalArgumentException(i +" or "+length +" error"); + } + for(int j=i;j101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list==null){ + throw new NullPointerException("List is null"); + } + int[] result = new int[list.size()]; + int index = 0; + for(Iterator iter = list.iterator();iter.hasNext();){ + int LinkIndex = (int)iter.next(); + result[index] = (int)get(LinkIndex); + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + if(list == null){ + throw new NullPointerException("List is null"); + } + int index = 0; + for(Node cur = head.next ; cur !=null ; cur = cur.next){ + for(Node newList = list.head.next ; newList != null; newList = newList.next ){ + if(Objects.deepEquals(cur.data, newList.data)){ + remove(index); + } + } + index++; + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + for(Node current=head.next;current!=null;current=current.next){ + Node nextNode = current.next; + + if(current.data.equals(nextNode.data)){ + Node nextNodeNext = nextNode.next; + if(nextNodeNext==null){ + current.next = null; + }else{ + current.next = nextNodeNext; + nextNode.next = null; + } + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max) { + if (min + max > size && min == max) { + throw new IndexOutOfBoundsException("Arguement is Illegal"); + } + int index = 0; + for (Node curr = head.next; curr != null; curr = curr.next) { + if(((int)curr.data>min) && ((int)curr.data { + public boolean add(T o); + + public boolean add(int index, T o); + + public T get(int index); + + T set(int index, T element); + + public T remove(int index); + + public T remove(T o); + + public int size(); + + public boolean isEmpty(); + + public Iterator iterator(); + + public boolean contains(Object o); + + int indexOf(Object o); + + + Object[] toArray(); + + void clear(); + +} diff --git a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java index 06944cd8b1..4acbbf8880 100644 --- a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java +++ b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java @@ -64,7 +64,7 @@ public void testFibonacci() { public void testGetPrimes() { int[] primes = {2,3,5,7,11,13,17,19}; int max = 23; - Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(max)); + Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(27)); } @Test diff --git a/group04/351121278/src/com/coding/download/DownloadThread.java b/group04/351121278/src/com/coding/download/DownloadThread.java new file mode 100644 index 0000000000..e0b396a5e6 --- /dev/null +++ b/group04/351121278/src/com/coding/download/DownloadThread.java @@ -0,0 +1,34 @@ +package com.coding.download; + +import com.coding.download.api.Connection; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + File file; + + public DownloadThread(File file, Connection conn, int startPos, int endPos){ + this.file = file; + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ + try { + System.out.println("DownloadThread.run"); + byte[] buffer = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile(file, "rw"); + raf.seek(startPos); + raf.write(buffer, 0, buffer.length); + raf.close(); + } catch (IOException e) { + System.out.println("e = " + e.getMessage()); + } + } +} diff --git a/group04/351121278/src/com/coding/download/FileDownloader.java b/group04/351121278/src/com/coding/download/FileDownloader.java new file mode 100644 index 0000000000..13d24f5b2b --- /dev/null +++ b/group04/351121278/src/com/coding/download/FileDownloader.java @@ -0,0 +1,76 @@ +package com.coding.download; + + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; + +import java.io.File; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + + conn = cm.open(this.url); + File file = new File("D:/test"); + int length = conn.getContentLength(); + for (int i=0; i<3; i++) { + new DownloadThread(file, conn, 0, length-1).start(); + } + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group04/351121278/src/com/coding/download/FileDownloaderTest.java b/group04/351121278/src/com/coding/download/FileDownloaderTest.java new file mode 100644 index 0000000000..84fbc8afa2 --- /dev/null +++ b/group04/351121278/src/com/coding/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.coding.download; + +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; +import com.coding.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://localhost:8080/test.jpg"; + + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/351121278/src/com/coding/download/api/Connection.java b/group04/351121278/src/com/coding/download/api/Connection.java new file mode 100644 index 0000000000..bd75d6cad0 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coding.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos, int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/351121278/src/com/coding/download/api/ConnectionException.java b/group04/351121278/src/com/coding/download/api/ConnectionException.java new file mode 100644 index 0000000000..1f57f86606 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/ConnectionException.java @@ -0,0 +1,10 @@ +package com.coding.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(String exceptionMessage) { + + } + public ConnectionException() { + } +} diff --git a/group04/351121278/src/com/coding/download/api/ConnectionManager.java b/group04/351121278/src/com/coding/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1d1a83caf2 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coding.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/351121278/src/com/coding/download/api/DownloadListener.java b/group04/351121278/src/com/coding/download/api/DownloadListener.java new file mode 100644 index 0000000000..c41045b0e8 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coding.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..7d524ec4a0 --- /dev/null +++ b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java @@ -0,0 +1,50 @@ +package com.coding.download.impl; + +import com.coding.download.api.Connection; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + + +public class ConnectionImpl implements Connection { + + private static final int THEAD_COUNT = 3; + private URL url; + private HttpURLConnection httpURLConnection; + private final int BUFFER_SIZE = 1024; + + public ConnectionImpl(URL url) { + this.url = url; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + URLConnection urlConnection = url.openConnection(); + httpURLConnection = (HttpURLConnection)urlConnection; + httpURLConnection.setRequestMethod("GET"); + InputStream in = httpURLConnection.getInputStream(); + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + int len; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((len = in.read(buffer)) != -1) { + byteOutputStream.write(buffer, startPos, len); + } + return byteOutputStream.toByteArray(); + } + + @Override + public int getContentLength() { + return httpURLConnection.getContentLength(); + } + + @Override + public void close() { + httpURLConnection.disconnect(); + } + +} diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..c07a0b545a --- /dev/null +++ b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,23 @@ +package com.coding.download.impl; + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; + +import java.net.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + URL urlObj; + try { + urlObj = new URL(url); + } catch (MalformedURLException e) { + throw new ConnectionException("URL无法访问" + e.getMessage()); + } + return new ConnectionImpl(urlObj); + } + +} diff --git a/group04/474772605/.classpath b/group04/474772605/.classpath index 28e2b79383..8d7ead9fe8 100644 --- a/group04/474772605/.classpath +++ b/group04/474772605/.classpath @@ -1,7 +1,11 @@ + + + + diff --git a/group04/474772605/jsp/homepage.jsp b/group04/474772605/jsp/homepage.jsp new file mode 100644 index 0000000000..83fa84db7d --- /dev/null +++ b/group04/474772605/jsp/homepage.jsp @@ -0,0 +1,12 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + + +homepage + + + + + \ No newline at end of file diff --git a/group04/474772605/jsp/showLogin.jsp b/group04/474772605/jsp/showLogin.jsp new file mode 100644 index 0000000000..1e6cda01b1 --- /dev/null +++ b/group04/474772605/jsp/showLogin.jsp @@ -0,0 +1,12 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + + +showLogin + + + + + \ No newline at end of file diff --git a/group12/382266293/src/com/coderising/action/LoginAction.java b/group04/474772605/src/com/coderising/action/LoginAction.java similarity index 95% rename from group12/382266293/src/com/coderising/action/LoginAction.java rename to group04/474772605/src/com/coderising/action/LoginAction.java index b1224eb80d..69ad2750c0 100644 --- a/group12/382266293/src/com/coderising/action/LoginAction.java +++ b/group04/474772605/src/com/coderising/action/LoginAction.java @@ -1,39 +1,40 @@ -package com.coderising.action; - -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @author liuxin - * - */ -public class LoginAction{ - private String name ; - private String password; - private String message; - - public String getName() { - return name; - } - - public String getPassword() { - return password; - } - - public String execute(){ - if("test".equals(name) && "1234".equals(password)){ - this.message = "login successful"; - return "success"; - } - this.message = "login failed,please check your user/pwd"; - return "fail"; - } - - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } -} \ No newline at end of file +package com.coderising.action; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/474772605/src/com/coderising/action/LogoutAction.java b/group04/474772605/src/com/coderising/action/LogoutAction.java new file mode 100644 index 0000000000..10e4eb37c7 --- /dev/null +++ b/group04/474772605/src/com/coderising/action/LogoutAction.java @@ -0,0 +1,40 @@ +package com.coderising.action; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LogoutAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success1"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/474772605/src/com/coderising/action/Struts.java b/group04/474772605/src/com/coderising/action/Struts.java new file mode 100644 index 0000000000..7db0e4687f --- /dev/null +++ b/group04/474772605/src/com/coderising/action/Struts.java @@ -0,0 +1,122 @@ +package com.coderising.action; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.dom4j.Attribute; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + + + +public class Struts { + + + + public static void main(String[] args) throws DocumentException { + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + View view = Struts.runAction(actionName,params); + System.out.println(view.getJsp()); + System.out.println(view.getParameters()); + } + + + public static View runAction(String actionName, Map parameters) { + View view = new View(); + SAXReader reader = new SAXReader(); + //读取文件 转换成Document + org.dom4j.Document document; + try { + document = reader.read(new File("src/struts.xml")); + Element root = document.getRootElement(); + @SuppressWarnings("unchecked") + List elements = root.elements(); + for (Element element : elements) { + Attribute actionAttribute = element.attribute("name"); + Attribute classAttribute = element.attribute("class"); + if(actionName.equals(actionAttribute.getValue())){ + String clazz = null; + clazz = classAttribute.getValue(); + Object o = Class.forName(clazz).newInstance(); + for (Map.Entry entry : parameters.entrySet()) { + String name = entry.getKey(); + String value =entry.getValue(); + String methodname = "set"+name.substring(0,1).toUpperCase()+name.substring(1); + Method m = o.getClass().getMethod(methodname, String.class); + m.invoke(o, value); + + } + Method m3 = o.getClass().getMethod("execute"); + String result = (String) m3.invoke(o); + String jspPath = null; + List element1s = element.elements("result"); + if(result.equals("success")){ + for (int i = 0; i < element1s.size(); i++) { + Attribute attribute2 = element1s.get(i).attribute("name"); + if (attribute2.getValue().equals("success")) { + jspPath = element1s.get(i).getStringValue(); + } + } + }else if(result.equals("fail")){ + for (int i = 0; i < element1s.size(); i++) { + Attribute attribute2 = element1s.get(i).attribute("name"); + if (attribute2.getValue().equals("fail")) { + jspPath = element1s.get(i).getStringValue(); + } + } + } + HashMapviewparamterHashMap = new HashMap(); + Method[]methods = o.getClass().getMethods(); + String methodname; + for (int j = 0; j < o.getClass().getMethods().length; j++) { + methodname = methods[j].getName(); + if(methodname.startsWith("get")&&!methodname.equals("getClass")){ + String methodname1 = methods[j].getName(); + methodname1 = methodname.substring(3,4).toUpperCase()+methodname1.substring(4); + viewparamterHashMap.put(methodname1, methods[j].invoke(o)); + } + } + view.setJsp(jspPath); + view.setParameters(viewparamterHashMap); + return view; + } + } + } catch (Exception e) { + // TODO: handle exception + } + return null; + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + } + +} diff --git a/group04/474772605/src/com/coderising/action/StrutsTest.java b/group04/474772605/src/com/coderising/action/StrutsTest.java new file mode 100644 index 0000000000..c161c0f932 --- /dev/null +++ b/group04/474772605/src/com/coderising/action/StrutsTest.java @@ -0,0 +1,43 @@ +package com.coderising.action; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "com.coderising.action.LoginAction"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group04/474772605/src/com/coderising/action/View.java b/group04/474772605/src/com/coderising/action/View.java new file mode 100644 index 0000000000..11cb1872e5 --- /dev/null +++ b/group04/474772605/src/com/coderising/action/View.java @@ -0,0 +1,23 @@ +package com.coderising.action; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group04/474772605/src/com/coderising/array/ArrayUtil.java b/group04/474772605/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..ddb00c17b6 --- /dev/null +++ b/group04/474772605/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,146 @@ +package com.coderising.array; + +import java.util.ArrayList; +import java.util.Stack; + +import com.coding.basic.LinkedList; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public void reverseArray(int[] origin){ + Stack stack = new Stack(); + for (int i = 0; i < origin.length; i++) { + stack.add(origin[i]); + } + + for (int j = 0; j < stack.size(); j++) { + origin[j] = (Integer) stack.pop(); + } + + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray){ + ArrayList newarray = new ArrayList(); + for (int i = 0; i < oldArray.length; i++) { + if(0!=oldArray[i]){ + newarray.add(oldArray[i]); + } + } + int result [] = new int [newarray.size()]; + for (int j = 0; j < result.length; j++) { + result[j]=newarray.get(j); + } + + return result; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2){ + ArrayList newarray = new ArrayList(); + for (int i = 0; i < array1.length; i++) { + newarray.add(i, array1[i]); + } + for (int j = 0; j < array2.length; j++) { + if (newarray.get(j)>array2[j]&&newarray.get(j+1)>array2[j]) { + newarray.add(j+1, array2[j]); + } + } + + int result [] = new int [newarray.size()]; + for (int z = 0; z < result.length; z++) { + result[z]=newarray.get(z); + } + return result; + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public int[] grow(int [] oldArray, int size){ + ArrayList newarray = new ArrayList(); + for (int i = 0; i < oldArray.length; i++) { + newarray.add(i, oldArray[i]); + } + while (newarray.size()='A'&&(char)num <='z'){ + n1++; + } + if((char)num >='A'&&(char)num <='Z'){ + n2++; + } + } + } + reader.close(); + System.out.println(n1+""+n2); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + + + public float method(){ + return 13.21f; + } + + + + + } + + + + + + + + + + + diff --git a/group04/474772605/src/com/coding/iostreams/test.java b/group04/474772605/src/com/coding/iostreams/test.java new file mode 100644 index 0000000000..1bd474ca7b --- /dev/null +++ b/group04/474772605/src/com/coding/iostreams/test.java @@ -0,0 +1,14 @@ +package com.coding.iostreams; + +public interface test { + public float method(); + +} + + + + + + + + diff --git a/group04/474772605/test/Test.java b/group04/474772605/test/Test.java new file mode 100644 index 0000000000..8c0f62930b --- /dev/null +++ b/group04/474772605/test/Test.java @@ -0,0 +1,50 @@ + + + import java.io.File; + import java.io.FileInputStream; + import java.io.InputStreamReader; + import java.io.Reader; + + + + + public class Test{ + static int n1 =0 ; + static int n2 =0 ; + + public static void main(String[] args) throws Exception{ + + Test.readFileByChars("D://Text.txt"); + + System.out.println("字母个数为:"+n1+" 字母个数为"+n2); + + } + + public static void readFileByChars(String fileName) { + File file = new File(fileName); + Reader reader = null; + try { + System.out.println("以字符为单位读取文件内容,一次读一个字节:"); + // 一次读一个字符 + reader = new InputStreamReader(new FileInputStream(file)); + int tempchar; + while ((tempchar = reader.read()) != -1) { + // 对于windows下,\r\n这两个字符在一起时,表示一个换行。 + // 但如果这两个字符分开显示时,会换两次行。 + // 因此,屏蔽掉\r,或者屏蔽\n。否则,将会多出很多空行。 + if (((char) tempchar) != '\r') { + System.out.print((char) tempchar); + n1++; + if((char)tempchar >='A'&&(char)tempchar<='Z'){ + n2++; + } + + } + } + reader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + diff --git a/group04/474772605/test/com/coding/basic/Heros.java b/group04/474772605/test/com/coding/basic/Heros.java new file mode 100644 index 0000000000..878204aede --- /dev/null +++ b/group04/474772605/test/com/coding/basic/Heros.java @@ -0,0 +1,51 @@ +package com.coding.basic; + +import java.lang.reflect.Method; + +public class Heros { + private String name;//名字 + private String type;//类型 + private int camp;//0,近卫;1,天灾 + public Heros(){ + + } + /* + public Heros(String name, String type, int camp) { + + super(); + + this.name = name; + this.type = type; + this.camp = camp; + }*/ + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getCamp() { + return camp; + } + + public void setCamp(int camp) { + this.camp = camp; + } + + @Override + public String toString() { + return "Heros [\n name=" + name + ", \n type=" + type + ", \n camp=" + camp + "\n]"; + } + +} \ No newline at end of file diff --git a/group04/474772605/test/com/coding/basic/Test.java b/group04/474772605/test/com/coding/basic/Test.java new file mode 100644 index 0000000000..97f7254c82 --- /dev/null +++ b/group04/474772605/test/com/coding/basic/Test.java @@ -0,0 +1,43 @@ +package com.coding.basic; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class Test { + + public static void main(String args[]) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Foo foo = new Foo("这个一个Foo对象!"); + Class clazz = foo.getClass(); + Field[] abc =clazz.getDeclaredFields(); + + // Object value = getFieldValueByName(key, obj);  + Method m1 = clazz.getDeclaredMethod("outInfo"); + Method m2 = clazz.getDeclaredMethod("setMsg", String.class); + Method m3 = clazz.getDeclaredMethod("getMsg"); + m1.invoke(foo); + m2.invoke(foo, "重新设置msg信息!"); + String msg = (String) m3.invoke(foo); + System.out.println(msg); + } +} + +class Foo { + private String msg; + + public Foo(String msg) { + this.msg = msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void outInfo() { + System.out.println("这是测试Java反射的测试类"); + } +} diff --git a/group04/474772605/test/com/coding/basic/TestStack.java b/group04/474772605/test/com/coding/basic/TestStack.java new file mode 100644 index 0000000000..e4caa84d98 --- /dev/null +++ b/group04/474772605/test/com/coding/basic/TestStack.java @@ -0,0 +1,35 @@ +package com.coding.basic; + +import junit.framework.TestCase; + +public class TestStack extends TestCase{ +private Stack stack; + + +public void setUp() throws Exception { + stack = new Stack(); + +} + +public void testpop(){ +// Stack stack = new Stack(); + Object o = null ; + try { + stack.push(o); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + +} + + + + + + + +} diff --git a/group04/474772605/test/com/coding/basic/Testarray.java b/group04/474772605/test/com/coding/basic/Testarray.java new file mode 100644 index 0000000000..19edb9f85d --- /dev/null +++ b/group04/474772605/test/com/coding/basic/Testarray.java @@ -0,0 +1,22 @@ +package com.coding.basic; + +import junit.framework.TestCase; + +public class Testarray extends TestCase{ + + public void testararry(){ + Throwable tx = null; + try { + ArrayList n = new ArrayList(); + Object o = null ; + + n.add(o); + fail(); + } catch (Exception e) { + tx =e; + assertEquals(Exception.class, tx.getClass()); + assertEquals("对象不能为空", e.getMessage()); + } + } + +} diff --git a/group04/474772605/test/com/coding/basic/teest.java b/group04/474772605/test/com/coding/basic/teest.java new file mode 100644 index 0000000000..e8004c14b6 --- /dev/null +++ b/group04/474772605/test/com/coding/basic/teest.java @@ -0,0 +1,24 @@ +package com.coding.basic; + +import java.lang.reflect.Method; + +public class teest { + public static void main(String[] args) { + Class herosClass = Heros.class; + try { + Method m1 = herosClass.getMethod("setName",String.class); + Method m3 = herosClass.getMethod("setCamp",int.class); + Method m2 = herosClass.getMethod("getName"); + + + Object userInfo = herosClass.newInstance(); + System.out.println("调用构造函数:"+userInfo); + m1.invoke(userInfo,"影魔"); + m3.invoke(userInfo, 1); + System.out.println("调用set方法:"+userInfo); + System.out.println("调用get方法:"+m2.invoke(userInfo)); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..b465389a69 --- /dev/null +++ b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,83 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + + + +public class ClassFileLoader { + + private static final String CLASS_SUFFIX = ".class"; + private static final byte[] EMPTY_BYTES = new byte[0]; + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + if(StringUtils.isEmpty(className)) { + return EMPTY_BYTES; + } + String child = className.replaceAll("\\.", "\\\\") + CLASS_SUFFIX; + for (String parent: clzPaths) { + File file = new File(parent, child); + if(file.exists()) { + return doReadBinaryCode(file); + } + } + return EMPTY_BYTES; + } + + + private byte[] doReadBinaryCode(File file) { + FileInputStream fis = null; + ByteArrayOutputStream baos = null; + try { + fis = new FileInputStream(file); + baos = new ByteArrayOutputStream(); + byte[] b = new byte[1024]; + int len = 0; + while((len = fis.read(b)) > 0) { + baos.write(b, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + new RuntimeException(e); + } finally { + close(baos); + close(fis); + } + return EMPTY_BYTES; + } + + + private void close(Closeable stream) { + if(stream != null ) { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + StringBuilder builder = new StringBuilder(); + for (String path : clzPaths) { + builder.append(path).append(";"); + } + if(builder.length() > 0) { + builder = builder.deleteCharAt(builder.length() - 1); + } + return builder.toString(); + } + +} diff --git a/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..7b9ca5c34d --- /dev/null +++ b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,93 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + private static final String CAFEBABE = "cafebabe"; + static String path1 = "D:\\Dev\\git_repository\\coding2017\\group04\\498654356\\mini-jvm\\jvm\\target\\test-classes"; + static String path2 = "C:\\temp"; + + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals(CAFEBABE, acctualValue); + } + + + + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i size) { + return Arrays.copyOf(baos.toByteArray(), size); + } + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + try { + return url.openConnection().getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + try { + url.openStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..21c7916805 --- /dev/null +++ b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package org.coding.three.download.impl; + +import org.coding.three.download.api.Connection; +import org.coding.three.download.api.ConnectionException; +import org.coding.three.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/List.java b/group04/498654356/one/src/org/coding/three/list/List.java similarity index 83% rename from group01/1814014897/zhouhui/src/week01/BasicDataStructure/List.java rename to group04/498654356/one/src/org/coding/three/list/List.java index 7806b75ed3..f631a65ba3 100644 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/List.java +++ b/group04/498654356/one/src/org/coding/three/list/List.java @@ -1,4 +1,4 @@ -package week01.BasicDataStructure; +package org.coding.three.list; public interface List { public void add(Object o); diff --git a/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java new file mode 100644 index 0000000000..03601b055d --- /dev/null +++ b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java @@ -0,0 +1,422 @@ +package org.coding.three.list.impl; + +import java.util.Arrays; +import java.util.Iterator; + +import org.coding.three.list.List; +/** + * 单链表/单向链表 + */ +public class LinkedList implements List { + /** + * 0. head 节点存储数据 + * 1. 这里的 head 第一次添加之后 "引用" 将不再改变;"值" 可以被修改已表示往首节点插入新的值。 + * 2. 可以将 head 修改为对 node 引用, 不存储任何数据。 + */ + private Node head; + + public void add(Object o){ + Node node = new Node(o); + if(head == null){ //第一次 + head = node; + } else { + getNode(size() - 1).next = node; + } + } + + private Node getNode(int index) { + checkIndex(index); + Node node = head; + for(int i = 0; i < index; i++) { + node = node.next; + } + return node; + } + + private void checkIndex(int index) { + int size = size(); + if(index < 0 || index > (size - 1)) { + throw new IndexOutOfBoundsException("size = " + size + ", index = " + index); + } + } + public void add(int index , Object o){ + checkIndex(index); + if(index == 0) { //更新 head 的值, 将旧值创建新的Node插入到 head 后 + Object data = head.data; + head.data = o; + Node node = new Node(data); + node.next = head.next; + head.next = node; + } else { + Node pre = getNode(index - 1); + Node node = new Node(o); + node.next = pre.next; + pre.next = node; + } + } + public Object get(int index){ + checkIndex(index); + return getNode(index).data; + } + public Object remove(int index){ + checkIndex(index); + Object data = null; + if(index == 0) { + Node next = head.next; + data = head.data; + if(next == null) { + head = null; + } else { + head.data = next.data; + head.next = next.next; + next.next = null; + } + } else { + Node pre = getNode(index - 1); + Node node = pre.next; + pre.next = node.next; + node.next = null; + data = node.data; + } + return data; + } + + public int size(){ + Node temp = head; + int size = 0; + while(temp != null) { + size++; + temp = temp.next; + } + return size; + } + + public void addFirst(Object o){ + add(0, o); + } + public void addLast(Object o){ + add(o); + } + public Object removeFirst(){ + return remove(0); + } + public Object removeLast(){ + return remove(size() - 1); + } + public Iterator iterator(){ + return new LinkedIterator(); + } + + class LinkedIterator implements Iterator { + int cursor = 0; + int lastRet = -1; + @Override + public boolean hasNext() { + return cursor != LinkedList.this.size(); + } + + @Override + public Object next() { + int i = cursor; + Object data = LinkedList.this.get(i); + lastRet = i; + cursor = i + 1; + return data; + } + + @Override + public void remove() { + if(lastRet < - 1) { + throw new RuntimeException("非法操作"); + } + LinkedList.this.remove(lastRet); + cursor--; + lastRet = -1; + } + } + + private static class Node{ + Object data; + Node next; + public Node(Object data) { + super(); + this.data = data; + } + + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + int size = size(); + if(size < 2) { + return ; + } + int preIndex = 0; + int behindIndex = size - 1; + Node preNode = head; + while(preIndex < behindIndex) { + Node behindNode = getNode(behindIndex); + Object temp = preNode.data; + preNode.data = behindNode.data; + behindNode.data = temp; + preIndex++; + behindIndex--; + preNode = preNode.next; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(size() < 2) { + return; + } + int count = size() / 2; + Node preNode = getNode(count - 1); + Node nextNode = preNode.next; + preNode.next = null; + head.data = nextNode.data; + head.next = nextNode.next; + nextNode.next = null; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int index, int length){ + checkIndex(index); + int size = size(); + if(index + length > size) { + length = size; + } + if(index == 0 && length == size) { + head = null; + return; + } + int tempIndex = index + length - 1; + Node endNode = getNode(tempIndex); + Node nextNode = endNode.next; + endNode.next = null; + if(index == 0) { //head + Node nnextNode = nextNode.next; + nextNode.next = null; + head.data = nextNode.data; + head.next = nnextNode; + } else { + Node preStartNode = getNode(index - 1); + preStartNode.next = nextNode; + } + } + /** + * 假定当前链表和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){ + Iterator it = list.iterator(); + int[] array = new int[list.size()]; + int size = size(); + int length = 0; + while(it.hasNext()) { + int index = (int) it.next(); + if(index >= size) { + break; + } + array[length++] = (int) get(index); + } + if(length == array.length) { + return array; + } else { + return Arrays.copyOf(array, length); + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + Iterator it = list.iterator(); + while(it.hasNext()) { + Object next = it.next(); + Iterator iterator = this.iterator(); + while(iterator.hasNext()) { + if(next.equals(iterator.next())) { + iterator.remove(); + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(size() < 2) { + return; + } + Iterator it = iterator(); + Object pre = null; + while(it.hasNext()){ + Object data = it.next(); + if(pre != null && pre.equals(data)) { + it.remove(); + } else { + pre = data; + } + } + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + int size = size(); + if(size < 1) { + return; + } + int minVal = (int)get(0); + int maxVal = (int)get(size - 1); + if(minVal > min && maxVal < max) { //直接清空 + this.head = null; + return; + } + if(max <= minVal) { + return; + } + if(min >= maxVal) { + return; + } + int startIndex = getMinIndex(min, size); + int endIndex = getMaxIndex(max, size); + if(endIndex - startIndex < 0) { + return; + } + remove(startIndex, (endIndex - startIndex) + 1); + + } + + private int getMaxIndex(int max, int size) { + int start = 0; + int end = size - 1; + while(start < end) { + int index = (end + start) / 2; + int midVal = (int) get(index); + if(midVal == max) { + return index - 1; +// index = index - 1; +// Node node = getNode(index); +// if((int)node.data < maxVal) { +// return index ; +// }//不考虑重复 TODO + } + if(midVal > max) { + end = index - 1; + } else { + start = index + 1; + } + } + if((int)get(end) >= max) { + return 0; + } + return end; + } + + private int getMinIndex(int min, int size) { + int start = 0; + int end = size - 1; + while(start < end) { + int index = (end + start) / 2; + int midVal = (int) get(index); + if(midVal == min) { + return index + 1; +// Node node = getNode(index); //暂无考虑重复 TODO +// if(node.next != null && (int)node.next.data > midVal) { +// return index + 1; +// } else { +// while(node.next != null && (int)node.next.data == midVal) { // 重复值 +// node = node.next; +// index++; +// } +// return index; +// +// } + } + if(midVal > min) { + end = index - 1; + } else { + start = index + 1; + } + } + if((int)get(start) <= min) { + return size; + } + return start; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList linkedList = new LinkedList(); + if(list == null || size() == 0 || list.size() == 0) { + return linkedList; + } + Iterator it = iterator(); + int index = 0; + boolean iseqFlag = false; + boolean isgtFlag = false; + while(it.hasNext()) { + int v1 = (int) it.next(); + if(index != 0) { + if(iseqFlag) { + list.remove(0, index + 1); + iseqFlag = false; + } + if(isgtFlag) { + list.remove(0, index); + isgtFlag = false; + } + } + Iterator it2 = list.iterator(); + while(it2.hasNext()) { + int v2 = (int) it2.next(); + if(v2 == v1) { + linkedList.add(v1); + iseqFlag = true; + break; + } else if(v2 > v1) { + isgtFlag = true; + break; + } + index++; + } + if(index == list.size()) { //第二个链表中的值是否全部小于现在第一个链表中正在进行比较的值 + break; + } + } + return linkedList; + } +} diff --git a/group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java b/group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..d93b78ec32 --- /dev/null +++ b/group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package org.coding.four.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/group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java b/group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java new file mode 100644 index 0000000000..fcaecf50ae --- /dev/null +++ b/group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java @@ -0,0 +1,61 @@ +package org.coding.three.download; + +import org.coding.three.download.api.ConnectionManager; +import org.coding.three.download.api.DownloadListener; +import org.coding.three.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + +// String url = "http://7xq43s.com1.z0.glb.clouddn.com/yunanding-6.jpg"; +// String url = "http://www.yinwang.org/blog-cn/2016/11/17/all-about-hillary"; +// String url = "http://orig04.deviantart.net/93d4/f/2007/314/9/5/audrey_tautou_by_shimoda7.jpg"; + String url = "http://pic36.nipic.com/20131230/1081324_162447228136_2.jpg"; + String destpath = "D:/b.jpg"; + int threadCount = 3; + + FileDownloader downloader = new FileDownloader(url, destpath, threadCount); + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java b/group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java new file mode 100644 index 0000000000..884407397b --- /dev/null +++ b/group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java @@ -0,0 +1,477 @@ +package org.coding.three.list.impl; + +import static org.junit.Assert.fail; + +import java.util.Iterator; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class LinkedListTest { + private LinkedList linkedList; + + @Before + public void setUp() throws Exception { + linkedList = new LinkedList(); + } + + @After + public void tearDown() throws Exception { + linkedList = null; + } + + @Test + public void testAddObject() { + int expected = 0; + int actual = linkedList.size(); + Assert.assertEquals(expected, actual); + + linkedList.add(1); + expected = 1; + actual = linkedList.size(); + Assert.assertEquals(expected, actual); + + linkedList.add(2); + expected = 2; + actual = linkedList.size(); + Assert.assertEquals(expected, actual); + } + + @Test + public void testAddIntObject() { + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + + linkedList.add(0, 4); + int expected = 4; + int actual = (int) linkedList.get(0); + Assert.assertEquals(expected, actual); + Assert.assertEquals(4, linkedList.size()); + + linkedList.add(2, 5); + Assert.assertEquals(5, linkedList.size()); + expected = 5; + actual = (int) linkedList.get(2); + Assert.assertEquals(expected, actual); + + } + + @Test + public void testGet() { + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + + int expected = 1; + int actual = (int) linkedList.get(0); + Assert.assertEquals(expected, actual); + + expected = 2; + actual = (int) linkedList.get(1); + Assert.assertEquals(expected, actual); + + expected = 3; + actual = (int) linkedList.get(2); + Assert.assertEquals(expected, actual); + } + + @Test + public void testRemoveInt() { + linkedList.add(1); + + int v = (int) linkedList.remove(0); + Assert.assertEquals(1, v); + Assert.assertEquals(0, linkedList.size()); + + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + + v = (int) linkedList.remove(1); + Assert.assertEquals(2, v); + Assert.assertEquals(2, linkedList.size()); + + linkedList.add(4); + linkedList.add(5); + linkedList.add(6); + + v = (int) linkedList.remove(linkedList.size() - 1); + Assert.assertEquals(6, v); + Assert.assertEquals(4, linkedList.size()); + } + + @Test + public void testSize() { + Assert.assertEquals(0, linkedList.size()); + linkedList.add(1); + Assert.assertEquals(1, linkedList.size()); + linkedList.remove(0); + Assert.assertEquals(0, linkedList.size()); + } + + @Test + public void testAddFirst() { + linkedList.add(4); + linkedList.add(5); + linkedList.add(6); + linkedList.addFirst(1); + Assert.assertEquals(4, linkedList.size()); + Assert.assertEquals(1, linkedList.get(0)); + } + + @Test + public void testAddLast() { + linkedList.addLast(1); + Assert.assertEquals(1, linkedList.size()); + Assert.assertEquals(1, linkedList.get(0)); + linkedList.addLast(2); + Assert.assertEquals(2, linkedList.size()); + Assert.assertEquals(2, linkedList.get(1)); + } + + @Test + public void testRemoveFirst() { + linkedList.add(4); + linkedList.add(5); + linkedList.add(6); + int v = (int) linkedList.removeFirst(); + Assert.assertEquals(2, linkedList.size()); + Assert.assertEquals(4, v); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testRemoveFirstException() { + linkedList.removeFirst(); + } + + @Test + public void testRemoveLast() { + linkedList.add(4); + int v = (int) linkedList.removeLast(); + Assert.assertEquals(0, linkedList.size()); + Assert.assertEquals(4, v); + + linkedList.add(5); + linkedList.add(6); + v = (int) linkedList.removeLast(); + Assert.assertEquals(1, linkedList.size()); + Assert.assertEquals(6, v); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testRemoveLastException() { + linkedList.removeLast(); + } + @Test + public void testIterator() { + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + Iterator it = linkedList.iterator(); + int expected = 1; + while(it.hasNext()) { + Object v = it.next(); + Assert.assertEquals(expected++, v); + } + + } + + @Test + public void testIteratorRemove() { + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + Iterator it = linkedList.iterator(); + while(it.hasNext()) { + it.next(); + it.remove(); + } + Assert.assertEquals(0, linkedList.size()); + + } + @Test + public void testReverse() { + linkedList.add(3); + linkedList.add(7); + linkedList.add(10); + linkedList.reverse(); + Assert.assertEquals(10, linkedList.get(0)); + Assert.assertEquals(7, linkedList.get(1)); + Assert.assertEquals(3, linkedList.get(2)); + } + + @Test + public void testReverse2() { + linkedList.add(3); + linkedList.reverse(); + Assert.assertEquals(3, linkedList.get(0)); + } + + @Test + public void testReverse3() { + linkedList.add(3); + linkedList.add(7); + linkedList.reverse(); + Assert.assertEquals(7, linkedList.get(0)); + Assert.assertEquals(3, linkedList.get(1)); + } + + + + @Test + public void testRemoveFirstHalf() { + linkedList.add(2); + linkedList.add(5); + linkedList.add(7); + linkedList.add(8); + linkedList.removeFirstHalf(); + Assert.assertEquals(7, linkedList.get(0)); + Assert.assertEquals(8, linkedList.get(1)); + } + + @Test + public void testRemoveFirstHalf2() { + linkedList.add(2); + linkedList.add(5); + linkedList.add(7); + linkedList.add(8); + linkedList.add(10); + linkedList.removeFirstHalf(); + Assert.assertEquals(7, linkedList.get(0)); + Assert.assertEquals(8, linkedList.get(1)); + Assert.assertEquals(10, linkedList.get(2)); + } + + @Test + public void testRemoveIntInt() { + linkedList.add(2); + linkedList.add(5); + linkedList.add(7); + linkedList.add(8); + linkedList.add(10); + linkedList.remove(1, 2); + Assert.assertEquals(3, linkedList.size()); + Assert.assertEquals(2, linkedList.get(0)); + Assert.assertEquals(8, linkedList.get(1)); + Assert.assertEquals(10, linkedList.get(2)); + } + + + @Test + public void testRemoveIntIntFull() { + linkedList.add(2); + linkedList.add(5); + linkedList.add(7); + linkedList.add(8); + linkedList.add(10); + linkedList.remove(0, 10); + Assert.assertEquals(0, linkedList.size()); + } + + + @Test + public void testRemoveIntIntHead() { + linkedList.add(2); + linkedList.add(5); + linkedList.add(7); + linkedList.add(8); + linkedList.add(10); + linkedList.remove(0, 2); + Assert.assertEquals(3, linkedList.size()); + Assert.assertEquals(7, linkedList.get(0)); + Assert.assertEquals(8, linkedList.get(1)); + Assert.assertEquals(10, linkedList.get(2)); + } + + @Test + public void testGetElements() { +// 11->101->201->301->401->501->601->701 + linkedList.add(11); + linkedList.add(101); + linkedList.add(201); + linkedList.add(301); + linkedList.add(401); + linkedList.add(501); + linkedList.add(601); + linkedList.add(701); +// 1->3->4->6 + LinkedList list = new LinkedList(); + list.add(1); + list.add(3); + list.add(4); + list.add(6); + int[] actuals = linkedList.getElements(list ); + int[] expecteds = {101,301,401,601}; + Assert.assertArrayEquals(expecteds, actuals); + } + + + @Test + public void testGetElements2() { +// 11->101->201->301->401->501->601->701 + linkedList.add(11); + linkedList.add(101); + linkedList.add(201); + linkedList.add(301); + linkedList.add(401); + linkedList.add(501); + linkedList.add(601); + linkedList.add(701); +// 1->3->4->20 + LinkedList list = new LinkedList(); + list.add(1); + list.add(3); + list.add(4); + list.add(20); + int[] actuals = linkedList.getElements(list ); + int[] expecteds = {101,301,401}; + Assert.assertArrayEquals(expecteds, actuals); + } + + @Test + public void testSubtract() { + 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(11); + list.add(201); + list.add(501); + linkedList.subtract(list ); + Assert.assertEquals(5, linkedList.size()); + + } + + @Test + public void testSubtract2() { + linkedList.add(11); + linkedList.add(101); + LinkedList list = new LinkedList(); + list.add(11); + list.add(201); + list.add(501); + linkedList.subtract(list ); + Assert.assertEquals(1, linkedList.size()); + + } + + + @Test + public void testRemoveDuplicateValues() { + linkedList.add(11); + linkedList.add(101); + linkedList.add(201); + linkedList.add(201); + linkedList.add(201); + linkedList.add(301); + linkedList.add(301); + linkedList.add(401); + Assert.assertEquals(8, linkedList.size()); + linkedList.removeDuplicateValues(); + Assert.assertEquals(5, linkedList.size()); + Assert.assertEquals(301, linkedList.get(linkedList.size() - 2)); + Assert.assertEquals(201, linkedList.get(linkedList.size() - 3)); + + } + + @Test + public void testRemoveRange() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.removeRange(4, 6); + Assert.assertEquals(2, linkedList.size()); + + } + + @Test + public void testRemoveRange2() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.removeRange(0, 6); + Assert.assertEquals(0, linkedList.size()); + + } + + @Test + public void testRemoveRange3() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.removeRange(3, 5); + Assert.assertEquals(3, linkedList.size()); + + } + + @Test + public void testRemoveRange4() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.removeRange(1, 3); + Assert.assertEquals(3, linkedList.size()); + + } + + @Test + public void testRemoveRange5() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.add(6); + linkedList.removeRange(3, 5); + Assert.assertEquals(4, linkedList.size()); + + } + + @Test + public void testIntersection() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.add(6); + LinkedList list = new LinkedList(); + list.add(1); + list.add(3); + LinkedList newList = linkedList.intersection(list ); + Assert.assertEquals(2, newList.size()); + Assert.assertEquals(1, newList.get(0)); + Assert.assertEquals(3, newList.get(1)); + } + + @Test + public void testIntersection2() { + linkedList.add(1); + linkedList.add(3); + linkedList.add(5); + linkedList.add(6); + LinkedList list = new LinkedList(); + list.add(10); + list.add(13); + LinkedList newList = linkedList.intersection(list ); + Assert.assertEquals(0, newList.size()); + } + + @Test + public void testIntersection3() { + linkedList.add(3); + linkedList.add(5); + linkedList.add(6); + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + LinkedList newList = linkedList.intersection(list ); + Assert.assertEquals(0, newList.size()); + } + +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..702edb8bbd --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java @@ -0,0 +1,62 @@ +package com.coderising.download; + +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; + private RandomAccessFile tempFile = null; + public DownloadThread( Connection conn, RandomAccessFile tempFile,String treadName){ + super.setName(treadName); + this.conn = conn; + this.startPos = conn.getStartPos(); + this.endPos = conn.getEndPos(); + this.tempFile = tempFile; + } + public void run(){ + + byte buf[] = null; + int count = (endPos - startPos)/1024; + int seekPos = 0; + try { + for (int i = 1; i < count; i++) { + System.out.println(this.getName() + " : " + (startPos+ 1024*(i-1)) + "-------" + (startPos + 1024*i) ); + buf = new byte[1024]; + conn.read(buf); + seekPos = startPos+ 1024*(i-1); + if (0 != seekPos) { + seekPos--; + } + tempFile.seek(seekPos); + writeToFile(buf); + buf = null; + } + + System.out.println(this.getName() + " : " + (startPos+ 1024*(count-1)) + "------- " + (endPos) ); + buf = new byte[endPos-(startPos+ 1024*(count-1))]; + conn.read(buf); + seekPos = startPos+ 1024*(count-1)-1; + tempFile.seek(seekPos); + writeToFile(buf); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private synchronized void writeToFile(byte[] buf) throws IOException { + tempFile.write(buf, 0, buf.length); + } + + + + +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..8a76bb29b4 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java @@ -0,0 +1,115 @@ +package com.coderising.download; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.net.URL; +import java.util.UUID; + +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 localPath = ""; + private DownloadListener listener; + private 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方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + try { + + int length = cm.open(url).getContentLength(); + RandomAccessFile tempFile = CreateTempFile(localPath,cm.open(url)); + + int step = length / 4; + DownloadThread downloadThread0 = new DownloadThread(cm.open(this.url,0,step-1),tempFile,"downLoad_Thread0"); + DownloadThread downloadThread1 = new DownloadThread(cm.open(this.url,step,2*step-1),tempFile,"downLoad_Thread1"); + DownloadThread downloadThread2 = new DownloadThread(cm.open(this.url,2*step,3*step-1),tempFile,"downLoad_Thread2"); + DownloadThread downloadThread3 = new DownloadThread(cm.open(this.url,3*step,length),tempFile,"downLoad_Thread3"); + downloadThread0.start(); + downloadThread1.start(); + downloadThread2.start(); + downloadThread3.start(); + + while(true) { + if (!(downloadThread0.isAlive()||downloadThread1.isAlive()||downloadThread2.isAlive()||downloadThread3.isAlive())) { + tempFile.close(); + this.listener.notifyFinished(); + break; + } + } + + } catch (ConnectionException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + private RandomAccessFile CreateTempFile(String path,Connection _conn) { + String tempFileName = UUID.randomUUID().toString() + ".jpg"; + RandomAccessFile randomAccessFile = null; + try { + randomAccessFile = new RandomAccessFile(path + File.separator +tempFileName,"rw"); + randomAccessFile.setLength(_conn.getContentLength()); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return randomAccessFile; + } + + private boolean ChangeFileName(File _f,Connection _conn) { + String fileName = _conn.getURL().getFile().substring(url.lastIndexOf("/")); + return _f.renameTo(new File(_f.getAbsolutePath()+File.separator+fileName)); + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + public String getLocalPath() { + return localPath; + } + + public void setLocalPath(String localPath) { + this.localPath = localPath; + } + +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..9f54c9ef47 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,58 @@ +package com.coderising.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "https://static.oschina.net/uploads/img/201701/09170848_HsPK.jpg"; + + FileDownloader downloader = new FileDownloader(url); + downloader.setLocalPath("E:/temp_backup/temp"); + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..598591b990 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java @@ -0,0 +1,29 @@ +package com.coderising.download.api; + +import java.io.IOException; +import java.net.URL; + +public interface Connection { + + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public int read(byte data[]) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); + + public URL getURL(); + public int getStartPos(); + public int getEndPos(); +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..95fb1d444d --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + private static final long serialVersionUID = 4776347926322882920L; +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..76024894f6 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,11 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url,int startPos ,int endPos) throws ConnectionException; + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/DownloadListener.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/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/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..ee7bbd4fc2 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,87 @@ +package com.coderising.download.impl; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + + private URLConnection uc = null; + private BufferedInputStream bs = null; + private URL url; + int startPos; + int endPos; + public ConnectionImpl(String path,int _startPos,int _endPos) throws Exception { + try { + if (startPos >= _endPos || _startPos < 0) { + throw new IllegalArgumentException(); + } + this.startPos = _startPos; + this.endPos = _endPos; + url = new URL(path); + uc = url.openConnection(); + uc.setRequestProperty("Range", "bytes=" + _startPos + "-" + _endPos); + bs = new BufferedInputStream(uc.getInputStream()); + } catch (MalformedURLException e) { + e.printStackTrace(); + throw e; + } catch (IOException e) { + e.printStackTrace(); + throw e; + } + } + public ConnectionImpl(String path) throws Exception { + try { + + url = new URL(path); + uc = url.openConnection(); + } catch (MalformedURLException e) { + e.printStackTrace(); + throw e; + } catch (IOException e) { + e.printStackTrace(); + throw e; + } + } + + public int read(byte data[]) { + int ret = 0; + try { + ret = bs.read(data); + } catch (IOException e) { + e.printStackTrace(); + } + return ret; + } + + public int getContentLength() { + return uc.getContentLength(); + } + + public URL getURL() { + return url; + } + + public void close() { + try { + if (null != bs) { + bs.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public int getStartPos() { + return this.startPos; + } + public int getEndPos() { + return this.endPos; + } + +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..838820f189 --- /dev/null +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,42 @@ +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 { + + public Connection open(String url,int startPos ,int endPos) throws ConnectionException { + if (null == url || "".equals(url)) { + throw new IllegalArgumentException("参数异常"); + } + + Connection conn = null; + try { + conn = new ConnectionImpl(url,startPos,endPos); + } catch (Exception e) { + e.printStackTrace(); + throw new ConnectionException(); + } + + return conn; + } + + public Connection open(String url) throws ConnectionException { + if (null == url || "".equals(url)) { + throw new IllegalArgumentException("参数异常"); + } + + Connection conn = null; + try { + conn = new ConnectionImpl(url); + } catch (Exception e) { + e.printStackTrace(); + throw new ConnectionException(); + } + + return conn; + } + +} diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java index c168b5efa8..71ead0324f 100644 --- a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java @@ -1,5 +1,7 @@ package com.coding.basic; +import java.util.concurrent.CyclicBarrier; + /** * @ClassName: ArrayList * @Description: 自增长数组 @@ -116,4 +118,5 @@ private boolean checkOutOfBounds() { return true; } } + } diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java index a824ad9372..1d8205dbed 100644 --- a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java +++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java @@ -1,5 +1,7 @@ package com.coding.basic; +import java.util.concurrent.CyclicBarrier; + /** * @ClassName: LinkedList @@ -129,6 +131,219 @@ private static class Node{ public String toString() { return "{" + this.data +" |---}--->"; } + } + + + //数据结构习题 + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public boolean reverse(){ + if (this.size()<=0) { + return false; + } + Stack stack = new Stack(); + + while(this.size()>0) { + stack.push(this.removeFirst()); + } + while(stack.size()>0) { + this.addLast(stack.pop()); + } + + return true; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public boolean removeFirstHalf(){ + if (this.size()<=0) { + return false; + } + //计算中间位置 + int tempCount = this.size(); + tempCount = tempCount%2 == 0 ? tempCount/2 : (tempCount-1)/2; + tempCount--; + while(tempCount >= 0) { + this.removeFirst(); + tempCount --; + } + return true; } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i<0|| i>=size) { + throw new IllegalArgumentException("下标超出链表范围!"); + } + if (!(length>0|| (i+1+length)<=this.size())) { + throw new IllegalArgumentException("参数非法!"); + } + + Node tempHead = head; + head = getNode(i-1); + while(length-->0){ + this.removeFirst(); + } + head = tempHead; + } + + /** + * 获取第i个元素的引用 + */ + public Node getNode(int index) { + if(index<0|| index>=size) { + throw new IllegalArgumentException("下标超出链表范围!"); + } + Node tempHead = head; + int i = 0; + while(i++ < index) { + tempHead = tempHead.next; + } + + return tempHead.next; + } + + + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public Integer[] getElements(LinkedList list){ + int listSizeB = list.size(); + int i=0; + Integer res[] = new Integer[listSizeB]; + while(listSizeB-- > 0) { + res[i] = (Integer) this.get((Integer)list.get(i)); + i++; + } + return res; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + * @param list + */ + + public void subtract(LinkedList list){ + Node tempNodePre = this.head; + Node tempNode = this.head.next; + Node tempNodeB = list.head.next; + Node temp = null; + while(null != tempNode && null != tempNodeB) { + Integer a = (Integer) tempNode.data; + Integer b = (Integer) tempNodeB.data; + if (a < b) { + tempNodePre = tempNodePre.next; + tempNode = tempNode.next; + } else if(a > b){ + tempNodeB = tempNodeB.next; + }else { + temp = tempNode; + tempNodePre.next = tempNode.next; + tempNode = tempNode.next; + temp.next = null; + temp = null; + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + Node tempPre = this.head; + Node tempCur = this.head.next; + Node temp = null; + while(null != tempCur) { + Integer a = (Integer) tempPre.data; + Integer b = (Integer) tempCur.data; + if(a == b) { + temp = tempCur; + tempPre.next = tempCur.next; + tempCur = tempCur.next; + temp.next = null; + temp = null; + }else { + tempPre = tempPre.next; + tempCur = tempCur.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if (min<0 || max=min) { + preMin = pre; + } + if (a<=max && b>max) { + preMax = pre; + } + pre = pre.next; + cur = cur.next; + } + preMin.next = preMax.next; + preMax = null; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList listB){ + Node nodeA = this.head.next; + Node nodeB = listB.head.next; + LinkedList listC = new LinkedList(); + while (null != nodeA && null != nodeB) { + Integer a = (Integer) nodeA.data; + Integer b = (Integer) nodeB.data; + if (a>b) { + nodeB = nodeB.next; + } else if(a7->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/group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..d2bed45b48 --- /dev/null +++ b/group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedOutputStream; +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.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +import javax.annotation.Resources; + + + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + InputStream ips = null; + ByteArrayOutputStream bao = null; + try { + String name=className.replace(".", "\\")+".class"; + for(int i=0;i 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/group24/798277403/src/week2/litestruts/StrutsTest.java b/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java similarity index 96% rename from group24/798277403/src/week2/litestruts/StrutsTest.java rename to group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java index 5c4379d912..b8c81faf3c 100644 --- a/group24/798277403/src/week2/litestruts/StrutsTest.java +++ b/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java @@ -1,11 +1,11 @@ -package week2.litestruts; - -import org.junit.Assert; -import org.junit.Test; +package com.coderising.litestruts; import java.util.HashMap; import java.util.Map; +import org.junit.Assert; +import org.junit.Test; + diff --git a/group15/1502_1617273078/src/com/coderising/litestruts/View.java b/group04/844028312/three/src/com/coderising/litestruts/View.java similarity index 100% rename from group15/1502_1617273078/src/com/coderising/litestruts/View.java rename to group04/844028312/three/src/com/coderising/litestruts/View.java diff --git a/group04/844028312/three/src/com/coding/basic/ArrayList.java b/group04/844028312/three/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..1f185736f9 --- /dev/null +++ b/group04/844028312/three/src/com/coding/basic/ArrayList.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData = new Object[100]; + + public void add(Object o){ + + } + public void add(int index, Object o){ + + } + + public Object get(int index){ + return null; + } + + public Object remove(int index){ + return null; + } + + public int size(){ + return -1; + } + + public Iterator iterator(){ + return null; + } + +} diff --git a/group04/844028312/three/src/com/coding/basic/BinaryTreeNode.java b/group04/844028312/three/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group04/844028312/three/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/work_1_20170225/src/com/coding/basic/Iterator.java b/group04/844028312/three/src/com/coding/basic/Iterator.java similarity index 100% rename from group14/187114392/work_1_20170225/src/com/coding/basic/Iterator.java rename to group04/844028312/three/src/com/coding/basic/Iterator.java diff --git a/group04/844028312/three/src/com/coding/basic/LinkedList.java b/group04/844028312/three/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..df43a6dec7 --- /dev/null +++ b/group04/844028312/three/src/com/coding/basic/LinkedList.java @@ -0,0 +1,417 @@ +package com.coding.basic; + +import java.util.Arrays; + +public class LinkedList implements List { + + private Node head; + private Node last; + private int size=0; + public void add(Object o){ + if(head==null){ + head =new Node(); + head.data=o; + last=head; + } + else{ + Node temp=new Node(); + temp.data=o; + last.next=temp; + last=temp; + } + size++; + } + public boolean enCapacity(int index){ + if(index>=0&&index7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + Node temp1=last; + for(int i=size-2;i>=0;i--){ + Node temp2=indexOf(i); + temp1.next=temp2; + temp1=temp2; + } + head.next=null; + temp1=head; + head=last; + last=temp1; + } + + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(size>1){ + Node index=indexOf(size/2-1); + index.next=null; + last=index; + size=size-size/2; + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){//1 2 3 4 5 + if( i=0){ + int len=length+i>size? size-i:length; + int j=0; + while(j0 && i>=0){ + Node before=indexOf(i-1); + Node after=indexOf(length+i); + if(before==null&&after==null){ + head=null; + last=null; + size=0; + } + else if(before==null&&after!=null){ + head=after; + size=size-length; + } + else if(before!=null&&after==null){ + before.next=null; + last=before; + size=size-length; + } + else{ + before.next=after; + size=size-length; + } + }*/ + + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list==null){ + return null; + } + int size=list.size; + int jude=0; + int [] newInt=new int[size]; + while(jude0){ + int index=(int) list.get(jude); + if(index>=0&&index0){ + int index=(int) list.get(jude); + for(int i=0;imin){ + start=i; + } + if((int)temp.data>=max){ + end=i; + break; + } + i++; + temp=temp.next; + } + 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; + } + int i=0; + int j=0; + LinkedList c=new LinkedList(); + while(i(int)list.get(j)){ + j++; + } + else{ + i++; + } + } + return c; + } +} diff --git a/group04/844028312/three/src/com/coding/basic/LinkedListTest.java b/group04/844028312/three/src/com/coding/basic/LinkedListTest.java new file mode 100644 index 0000000000..0c965c90bd --- /dev/null +++ b/group04/844028312/three/src/com/coding/basic/LinkedListTest.java @@ -0,0 +1,145 @@ +package com.coding.basic; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class LinkedListTest { + private LinkedList linkedList; + @Before + public void setUp() throws Exception { + linkedList=new LinkedList(); + for(int i=0;i<10;i++){ + linkedList.add(i); + } + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddObject() { + + System.out.println(linkedList.size()); + } + + @Test + public void testAddIntObject() { + linkedList.add(10, "@"); + System.out.println(linkedList.size()); + } + + @Test + public void testGet() { + System.out.println(linkedList.get(100)); + } + + @Test + public void testRemoveInt() { + System.out.println(linkedList.remove(9)); + System.out.println(linkedList.size()); + } + + @Test + public void testSize() { + fail("Not yet implemented"); + } + + @Test + public void testAddFirst() { + linkedList.addFirst("aa"); + System.out.println(linkedList.size()); + } + + @Test + public void testAddLast() { + linkedList.addLast("bb"); + System.out.println(linkedList.size()); + } + + @Test + public void testRemoveFirst() { + linkedList.removeFirst(); + System.out.println(linkedList.size()); + } + + @Test + public void testRemoveLast() { + linkedList.removeLast(); + System.out.println(linkedList.size()); + } + + @Test + public void testIterator() { + fail("Not yet implemented"); + } + + @Test + public void testReverse() { + linkedList.reverse(); + System.out.println(linkedList.size()); + } + + @Test + public void testRemoveFirstHalf() { + linkedList.removeFirstHalf(); + System.out.println(linkedList.size()); + } + + @Test + public void testRemoveIntInt() { + linkedList.remove(2, 5);//0 1 2 3 4 5 6 7 8 9 + System.out.println(linkedList.size()); + } + + @Test + public void testGetElements() { + LinkedList list=new LinkedList(); + list.add(1); + list.add(3); + list.add(2); + list.add(7); + int [] a=linkedList.getElements(list); + System.out.println(a); + + } + + @Test + public void testSubtract() { + LinkedList list=new LinkedList(); + list.add(1); + list.add(3); + list.add(2); + list.add(10); + linkedList.subtract(list); + System.out.println(linkedList); + } + + @Test + public void testRemoveDuplicateValues() { + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.removeDuplicateValues(); + System.out.println(linkedList); + } + + @Test + public void testRemoveRange() { + linkedList.removeRange(2, 5); + System.out.println(linkedList); + } + + @Test + public void testIntersection() { + LinkedList list=new LinkedList(); + list.add(5); + list.add(6); + LinkedList c=linkedList.intersection(list); + System.out.println(c); + } + +} diff --git a/group15/1502_1617273078/src/com/coding/basic/List.java b/group04/844028312/three/src/com/coding/basic/List.java similarity index 100% rename from group15/1502_1617273078/src/com/coding/basic/List.java rename to group04/844028312/three/src/com/coding/basic/List.java diff --git a/group04/844028312/three/src/com/coding/basic/Queue.java b/group04/844028312/three/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..36e516e266 --- /dev/null +++ b/group04/844028312/three/src/com/coding/basic/Queue.java @@ -0,0 +1,19 @@ +package com.coding.basic; + +public class Queue { + + public void enQueue(Object o){ + } + + public Object deQueue(){ + return null; + } + + public boolean isEmpty(){ + return false; + } + + public int size(){ + return -1; + } +} diff --git a/group04/844028312/three/src/com/coding/basic/Stack.java b/group04/844028312/three/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..a5a04de76d --- /dev/null +++ b/group04/844028312/three/src/com/coding/basic/Stack.java @@ -0,0 +1,22 @@ +package com.coding.basic; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + } + + public Object pop(){ + return null; + } + + public Object peek(){ + return null; + } + public boolean isEmpty(){ + return false; + } + public int size(){ + return -1; + } +} diff --git a/group04/844028312/two/src/com/coderising/array/ArrayUtil.java b/group04/844028312/two/src/com/coderising/array/ArrayUtil.java index 309610c6be..504c07640e 100644 --- a/group04/844028312/two/src/com/coderising/array/ArrayUtil.java +++ b/group04/844028312/two/src/com/coderising/array/ArrayUtil.java @@ -12,14 +12,16 @@ public class ArrayUtil { * @return */ public void reverseArray(int[] origin){ + if(origin==null){ + return; + } int size=origin.length; - if(size>1){ - for(int i=0;iarray2[j]){ + newArray[count++]=array2[j++]; + + } + if(array1[i]0) - System.arraycopy(array1, 0, newArray, 0, size1); - if(size2>0) - System.arraycopy(array2,0, newArray, size1, size2); - for(int i=0;inewArray[j]){ - int temp=min; - min=newArray[j]; - newArray[i]=min; - newArray[j]=temp; - } - } + while(j==size1&&i2){ - a=new int[10]; + a=new int[max]; int record=2; do{ a[0]=1; a[1]=1; - if(a.length>record) - a[record]=a[record-2]+a[record-1]; - else{ - a=grow(a,3); - a[record]=a[record-2]+a[record-1]; - } + a[record]=a[record-2]+a[record-1]; record++; }while(a[record-1]1;i--){ - if(n%i==0){ - isPrime=false; + if(max>=2){ + while(n1;i--){ + if(n%i==0){ + isPrime=false; + break; + } + } - } - if(isPrime){ - if(record=min){ - while(true){ - boolean isPerfect=false;//是否是完数的标志 - if(max<=min){ - break; - } - int n=(int) Math.sqrt(min); - int count=0; - for(int i=n;i>=1;i--){ + while(min0;i--){ if(min%i==0){ - count=count+i; - int b=min/i; - if(b!=min) - count=count+b; + sum=sum+i; } } - if(count==min){ - isPerfect=true; - } - if(isPerfect){ - if(record - + diff --git a/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java b/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java index 0c9e702951..b4ac9cf2b9 100644 --- a/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java +++ b/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java @@ -9,23 +9,30 @@ public class ArrayList implements List { private Object[] elementData = new Object[3]; public void add(Object o){ - add(size,o); + ensureCapacity(size + 1); + elementData[size] = o; + size++; } + public void add(int index, Object o){ if (index > size){ throw new IndexOutOfBoundsException(); } + // 扩容 - if (size == elementData.length || index + 1 > elementData.length) { - int newLength = index + 1 > size * 2 ? index + 1 :size * 2; - elementData = Arrays.copyOf(elementData, newLength); - } + ensureCapacity(size + 1); + // 移动元素 System.arraycopy(elementData,index,elementData,index + 1 ,size-index); elementData[index] = o; size ++ ; } - + + private void ensureCapacity(int minCapacity) { + int newLength = Math.max(minCapacity, size * 2); + elementData = Arrays.copyOf(elementData, newLength); + } + public Object get(int index){ checkIndex(index); return elementData[index]; @@ -55,17 +62,17 @@ public Iterator iterator(){ private class ArrayListIterator implements Iterator { - private int currentIndex = 0; + private int position = 0; @Override public boolean hasNext() { - return currentIndex < size(); + return position < size(); } @Override public Object next() { - Object o = get(currentIndex); - currentIndex ++ ; + Object o = get(position); + position++ ; return o; } } diff --git a/group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java b/group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java new file mode 100644 index 0000000000..6239bc13d2 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java @@ -0,0 +1,50 @@ +package com.example.download; + + +import com.example.download.api.Connection; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CountDownLatch; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String file; + CountDownLatch latch; + + public DownloadThread( Connection conn, int startPos, int endPos,String file,CountDownLatch latch){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.file = file; + this.latch = latch; + } + public void run(){ + RandomAccessFile randomAccessFile = null; + try { + byte[] data = conn.read(startPos, endPos); + randomAccessFile = new RandomAccessFile(file, "rw"); + randomAccessFile.seek(startPos); + randomAccessFile.write(data); + latch.countDown(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + }finally { + try { + if (randomAccessFile != null) { + randomAccessFile.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + conn.close(); + } + } +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java b/group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java new file mode 100644 index 0000000000..743955e329 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java @@ -0,0 +1,76 @@ +package com.example.download; + + +import com.example.download.api.Connection; +import com.example.download.api.ConnectionException; +import com.example.download.api.ConnectionManager; +import com.example.download.api.DownloadListener; +import java.util.concurrent.CountDownLatch; + +public class FileDownloader { + + String url; + + String localFile; + + DownloadListener listener; + + ConnectionManager cm; + + private CountDownLatch latch = new CountDownLatch(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方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + int[][] array = Utils.split(length, 3); + for (int i = 0; i < 3; i++) { + new DownloadThread(conn,array[i][0],array[i][1],localFile,latch).start(); + } + + latch.await(); + + this.getListener().notifyFinished(); + + } catch (ConnectionException e) { + e.printStackTrace(); + } catch (InterruptedException 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/group04/916758663/learn03/src/main/java/com/example/download/Utils.java b/group04/916758663/learn03/src/main/java/com/example/download/Utils.java new file mode 100644 index 0000000000..521583d7e5 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/Utils.java @@ -0,0 +1,24 @@ +package com.example.download; + +/** + * Created by qilei on 17/3/26. + */ +public class Utils { + + public static int[][] split(int len, int count) { + int[][] result = new int[count][2]; + int baseLen = (int)Math.ceil(((double)len / count)); + for (int i = 0; i < count; i++) { + int startPos = baseLen * i ; + int endPos = baseLen * (i + 1) -1; + if (i == count - 1) { + if (endPos > len - 1) { + endPos = len - 1; + } + } + result[i][0] = startPos; + result[i][1] = endPos; + } + return result; + } +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java b/group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java new file mode 100644 index 0000000000..d3906b1859 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.example.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos, int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java new file mode 100644 index 0000000000..ffbd61ec31 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.example.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1888a879ef --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.example.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java b/group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java new file mode 100644 index 0000000000..9cc73ddee6 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.example.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..62ee66f1c5 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java @@ -0,0 +1,58 @@ +package com.example.download.impl; + +import com.example.download.api.Connection; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + + +public class ConnectionImpl implements Connection { + + private URL url; + + ConnectionImpl(String urlStr){ + try { + url = new URL(urlStr); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + URLConnection urlConnection = url.openConnection(); + urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + + endPos); + InputStream inputStream = urlConnection.getInputStream(); + int len = endPos + 1 - startPos; + int bytesRead = 0; + byte[] buffer = new byte[len]; + while (bytesRead < len) { + int result = inputStream.read(buffer, bytesRead, len - bytesRead); + if (result == -1){ + break; + } + bytesRead += result; + } + inputStream.close(); + return buffer; + } + + @Override + public int getContentLength() { + try { + URLConnection urlConnection = url.openConnection(); + return urlConnection.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + } + +} diff --git a/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..d346c4d350 --- /dev/null +++ b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,16 @@ +package com.example.download.impl; + + +import com.example.download.api.Connection; +import com.example.download.api.ConnectionException; +import com.example.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/group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java b/group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java new file mode 100644 index 0000000000..7dbeffd108 --- /dev/null +++ b/group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java @@ -0,0 +1,57 @@ +package com.example.download; + + +import com.example.download.api.ConnectionManager; +import com.example.download.api.DownloadListener; +import com.example.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by qilei on 17/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://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + String file = "/Users/qilei/tmp/tmp.jpg"; + FileDownloader downloader = new FileDownloader(url,file); + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + } + +} \ No newline at end of file diff --git a/group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java b/group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java new file mode 100644 index 0000000000..ff41d07731 --- /dev/null +++ b/group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java @@ -0,0 +1,31 @@ +package com.example.download; + +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +/** + * Created by qilei on 17/3/26. + */ +public class UtilsTest { + + @Test + public void testSplit(){ + int len = 10; + + int[][] result = Utils.split(10,3); + + assertThat(result[0][0]).isEqualTo(0); + assertThat(result[0][1]).isEqualTo(3); + assertThat(result[2][0]).isEqualTo(8); + assertThat(result[2][1]).isEqualTo(9); + } + + @Test + public void testMath(){ + double a = Math.ceil((double)10 / 3); + double b = Math.floor((double)10 / 3); + System.out.println(""); + + } + +} diff --git a/group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java b/group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java new file mode 100644 index 0000000000..7b21df4109 --- /dev/null +++ b/group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java @@ -0,0 +1,49 @@ +package com.example.download.impl; + +import static org.assertj.core.api.Assertions.*; + +import com.example.download.api.Connection; +import com.example.download.api.ConnectionException; +import com.example.download.api.ConnectionManager; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by qilei on 17/3/24. + */ +public class ConnectionImplTest { + + private Connection connection; + + @Before + public void setup(){ + ConnectionManager cm = new ConnectionManagerImpl(); + String url ="http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + try { + connection = cm.open(url); + } catch (ConnectionException e) { + e.printStackTrace(); + } + } + + @Test + public void read() throws Exception { + byte[] data = null; + data = connection.read(0, 35469); + assertThat(data.length).isEqualTo(35470); + + data = connection.read(0, 1023); + assertThat(data.length).isEqualTo(1024); + + data = connection.read(1024, 2023); + assertThat(data.length).isEqualTo(1000); + + } + + @Test + public void getContentLength() throws Exception { + int contentLength = connection.getContentLength(); + assertThat(contentLength).isEqualTo(35470); + } + +} \ No newline at end of file diff --git a/group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java b/group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..cb860bf053 --- /dev/null +++ b/group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java @@ -0,0 +1,70 @@ +package com.example.jvm.loader; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +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 filePartPath = className.replace(".", "/") + ".class"; + for (String clzPath : clzPaths) { + String filePath = clzPath + "/" + filePartPath; + File file = new File(filePath); + if (file.exists()) { + try { + FileInputStream inputStream = new FileInputStream(file); + int bytesRead = 0; + int len = inputStream.available(); + byte[] buffer = new byte[len]; + while (bytesRead < len) { + int result = inputStream.read(buffer, bytesRead, len - bytesRead); + if (result == -1){ + break; + } + bytesRead += result; + } + inputStream.close(); + return buffer; + } catch (FileNotFoundException e) { + e.printStackTrace(); + }catch (IOException e) { + e.printStackTrace(); + } + } + } + throw new RuntimeException("未找到类"); + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + String result = ""; + StringBuilder sb = new StringBuilder(); + for(String path : clzPaths){ + sb.append(path + ";"); + } + result = sb.toString(); + if (result != "") { + result = result.substring(0, result.length() - 1); + } + return result; + } + + + + + +} diff --git a/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java b/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..04bb301b5e --- /dev/null +++ b/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,78 @@ +package com.example.jvm.loader; + + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by qilei on 17/4/3. + */ +public class ClassFileLoaderTest { + + static String path1 = "/Users/qilei/idea/coding2017/coding2017/group04/916758663/minijvm/target/test-classes"; + static String path2 = "/Users/qilei/idea/coding2017/coding2017/group04/916758663/minijvm/target/classes"; + + @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.example.jvm.loader.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1054, byteCodes.length); + + } + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.example.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 clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws ClassNotFoundException, IOException { + if (clzPaths.size() == 0) { + return new byte[0]; + } + String actualPath = getActualPath(className); + + File f = new File(actualPath); + + if (!f.exists()) { + throw new ClassNotFoundException(actualPath); + } + + ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length()); + BufferedInputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(f)); + + byte[] buffer = new byte[1024]; + int len = 0; + + while (-1 != (len = is.read(buffer))) { + bos.write(buffer, 0, len); + } + + return bos.toByteArray(); + + } catch (IOException e) { + e.printStackTrace(); + throw e; + } finally { + is.close(); + bos.close(); + } + } + + private String getActualPath(String className) { + + String fileName = className.substring(className.lastIndexOf(".") + 1) + ".class"; + String dirPath = className.substring(0, className.lastIndexOf(".")).replace(".", "\\"); + + return clzPaths.get(clzPaths.size() - 1) + "\\" + dirPath + "\\" + fileName; //classPath 取最近添加的一个 + + } + + public void addClassPath(String path) { + + if (path == null) { + return; + } + + clzPaths.add(path); + + } + + public String getClassPath() { + + if (clzPaths.size() == 0) { + return ""; + } + + StringBuffer buffer = new StringBuffer(""); + + for (String str : clzPaths) { + buffer.append(str); + buffer.append(";"); + } + + return buffer.substring(0, buffer.length() - 1);// 去除最后一个分号 + + } + +} diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..287786b541 --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,95 @@ +package com.coderising.jvm.test; + +import java.io.IOException; + +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 = "E:\\practise\\group05\\1094051862\\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 ClassNotFoundException, IOException { + + 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() throws ClassNotFoundException, IOException{ + + 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); + + } + + /** + * 二进制数组转换成16进制 + * @param codes + * @return + */ + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i 0) { + accessNormally(pageNum); + capacity --; + } else { + Node node = first; + while(node != null) { + + if (node.pageNum == pageNum) { + accessNodeExisting(node); + return; + } + + node = node.next; + } + + accessNormally(pageNum); + + removeLast(); + } + + } + + private void accessNodeExisting(Node node) { + if (node.next == null) { //最后一个元素为要添加的元素 + removeLast(); + exchangeFirstWithNode(node); + } else if (node.prev != null) { //要添加的元素在中间 + Node n = node.next; + Node p = node.prev; + p.next = n; + n.prev = p; + + exchangeFirstWithNode(node); + } + } + + private void exchangeFirstWithNode(Node node) { + node.next = first; + first.prev = node; + node.prev = null; //忘记这个就会导致找不到第一个添加的元素,测试出现堆溢出 + first = node; + } + + private void removeLast() { + last = last.prev; + last.next = null; + } + + private void accessNormally(int pageNum) { + + Node temp = first; + first = new Node(); + first.pageNum = pageNum; + first.next = temp; + temp.prev = first; + + } + + private void accessFirst(int pageNum) { + + first = new Node(); + first.pageNum = pageNum; + last = first; + 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/group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..55bf75ec41 --- /dev/null +++ b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java @@ -0,0 +1,38 @@ +package com.coding.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()); + System.out.println(frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + System.out.println(frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + System.out.println(frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + System.out.println(frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + System.out.println(frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + System.out.println(frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + System.out.println(frame.toString()); + } + +} diff --git a/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java b/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..a15237f0cb --- /dev/null +++ b/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,46 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList<>(); + + public byte[] readBinaryCode(String className) { + String name = this.getClassPath() + File.separatorChar + className.replace('.', File.separatorChar) + ".class"; + File file = new File(name); + byte[] bytes = new byte[(int)file.length()]; + try { + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + while (bis.read(bytes) != -1) { + System.out.println(Arrays.toString(bytes)); + } + } catch (IOException e) { + e.printStackTrace(); + } + return bytes; + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + public String getClassPath() { + StringBuilder path = new StringBuilder(); + for (String str : clzPaths) { + path.append(str).append(";"); + } + return path.substring(0, path.length() - 1); + } + + +} diff --git a/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..ca669de57a --- /dev/null +++ b/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,74 @@ +package com.coderising.jvm.test; + +import com.coderising.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 = "D:\\git\\coding2017\\group05\\284422826\\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 ){ + 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/group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java b/group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..12e3d7efdd --- /dev/null +++ b/group05/284422826/src/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/group05/284422826/src/com/coding2017/basic/Queue.java b/group05/284422826/src/com/coding2017/basic/Queue.java index 57d63f43bf..0148cc7c38 100644 --- a/group05/284422826/src/com/coding2017/basic/Queue.java +++ b/group05/284422826/src/com/coding2017/basic/Queue.java @@ -1,5 +1,7 @@ package com.coding2017.basic; +import com.coding2017.basic.linklist.LinkedList; + import java.util.EmptyStackException; public class Queue { diff --git a/group05/284422826/src/com/coding2017/basic/ArrayList.java b/group05/284422826/src/com/coding2017/basic/array/ArrayList.java similarity index 100% rename from group05/284422826/src/com/coding2017/basic/ArrayList.java rename to group05/284422826/src/com/coding2017/basic/array/ArrayList.java diff --git a/group05/284422826/src/com/coderising/array/ArrayUtil.java b/group05/284422826/src/com/coding2017/basic/array/ArrayUtil.java similarity index 100% rename from group05/284422826/src/com/coderising/array/ArrayUtil.java rename to group05/284422826/src/com/coding2017/basic/array/ArrayUtil.java diff --git a/group05/284422826/src/com/coderising/array/ArrayUtilTest.java b/group05/284422826/src/com/coding2017/basic/array/ArrayUtilTest.java similarity index 100% rename from group05/284422826/src/com/coderising/array/ArrayUtilTest.java rename to group05/284422826/src/com/coding2017/basic/array/ArrayUtilTest.java diff --git a/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..d43bbc13d7 --- /dev/null +++ b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java @@ -0,0 +1,113 @@ +package com.coding2017.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 size = 0; + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + if (size < capacity) { + Node node = new Node(); + node.pageNum = pageNum; + if (first == null && last == null) { + node.prev = null; + node.next = null; + first = node; + last = node; + } else { + if (last.prev == null) { + last.prev = node; + node.next = last; + } else { + assert first != null; + first.prev = node; + node.next = first; + } + node.prev = null; + first = node; + } + size++; + } else { + Node node = last; + while (node != null) { + if (pageNum == node.pageNum) { + Node temp = node; + if(node == last){ + last = last.prev; + last.prev = temp.prev.prev; + last.next = null; + }else if(node == first){ + first = temp.next; + first.prev = null; + first.next = temp.next.next; + }else{ + node.next.prev = temp.prev; + node.prev.next = temp.next; + } + temp = null; + break; + } + node = node.prev; + } + + if(node == null){ + Node temp = last; + last = last.prev; + last.prev = temp.prev.prev; + last.next = null; + temp = null; + } + + Node newNode = new Node(); + newNode.pageNum = pageNum; + first.prev = newNode; + newNode.prev = null; + newNode.next = first; + first = newNode; + + } + + } + + 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/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..7e0e79767c --- /dev/null +++ b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding2017.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/group05/284422826/src/com/coding2017/basic/LinkedList.java b/group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java similarity index 98% rename from group05/284422826/src/com/coding2017/basic/LinkedList.java rename to group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java index fbc92ff474..e1dce5568c 100644 --- a/group05/284422826/src/com/coding2017/basic/LinkedList.java +++ b/group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java @@ -1,4 +1,7 @@ -package com.coding2017.basic; +package com.coding2017.basic.linklist; + +import com.coding2017.basic.Iterator; +import com.coding2017.basic.List; import java.util.Arrays; import java.util.NoSuchElementException; diff --git a/group05/289326186/src/com/coderising/download/DownloadThread.java b/group05/289326186/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..9690e741a2 --- /dev/null +++ b/group05/289326186/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,35 @@ +package com.coderising.download; + +import java.io.File; +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; + + public DownloadThread( Connection conn, int startPos, int endPos){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ + try { + byte[] b = conn.read(startPos, endPos); + String path = "D:" + File.separator + "test"+File.separator+"123.jpg"; + RandomAccessFile f = new RandomAccessFile(path, "rw"); + f.seek(startPos); + f.write(b); + f.close(); + System.out.println(Thread.currentThread().getName()+"线程下载完毕"); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} \ No newline at end of file diff --git a/group05/289326186/src/com/coderising/download/FileDownloader.java b/group05/289326186/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..d8a37c3abe --- /dev/null +++ b/group05/289326186/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,104 @@ +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; + + int threadCount = 3; + + private DownloadThread[] threads = new DownloadThread[threadCount]; + + int length = 0;//文件总长度 + + 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); + + length = conn.getContentLength(); + System.out.println("length:"+length); + + //计算每个线程需要下载的文件大小 + int perLen = 0; + int lastLen = 0; + int tail = length % threadCount; + perLen = length/threadCount; + if(tail == 0){ + lastLen = perLen; + }else{ + lastLen = perLen + tail; + } + for(int i=0; i parameters) String key = entry.getKey(); if(pd.getName().equals(key)){ Method setMethod = pd.getWriteMethod();//获得set方法 - setMethod .invoke(obj, entry.getValue());//调用 + setMethod.invoke(obj, entry.getValue());//调用 break; } } @@ -65,23 +65,14 @@ public static View runAction(String actionName, Map parameters) Method method = clazz.getMethod("execute", null); Object result = method.invoke(obj); Map map = new HashMap(); - if("success".equals(result)){ - map.put("message", "login successful"); - }else{ - map.put("message", "login failed,please check your user/pwd"); - } // 3. 通过反射找到对象的所有getter方法(例如 getMessage), // 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , // 放到View对象的parameters for(PropertyDescriptor pd : pds){ - for (Entry entry : parameters.entrySet()) { - String key = entry.getKey(); - if(pd.getName().equals(key)){ - Method getMethod = pd.getReadMethod();//获得get方法 - Object getresult = getMethod .invoke(obj);//调用 - map.put(pd.getName(), getresult.toString()); - break; - } + Method getMethod = pd.getReadMethod();//获得get方法 + Object getresult = getMethod.invoke(obj);//调用 + if(!"class".equals(pd.getName())){ + map.put(pd.getName(), getresult.toString()); } } view.setParameters(map); 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/structs.xml b/group06/1378560653/src/com/coderising/litestruts/structs.xml deleted file mode 100644 index dd598a3664..0000000000 --- a/group06/1378560653/src/com/coderising/litestruts/structs.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /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 0000000000000000000000000000000000000000..2d7096c7b76e18d939e82ad536755ce0ba7083e6 GIT binary patch literal 2437 zcmY+`X*d*G1HkbywycpQ+k~O)43!v_iD)8gs2E$;ne6M3YacPp++i@*lvJ{ev6pOv zDEm&fnHKw!Hp()t?!E7QpU$Uq&h!6tp7T4;v2+fQ7Gnnt5CQ=J9>70C#wfBa*C0bwzF1gP+^gi?K;JrS~DI0&}zgy!|1X1 zu;plRa@{gluw{{~qo}N0f>k`6+kbKX`3F2hh<2>=X<*Z07;PL)i{kmJ)6XDjZ};T< zq~la{Z=t{}TgZe(Sg?FTKtC@Uc^+8S6Fx=MU@j$ZLApm-rkWyaJA$UdL2M;ct1Mm# zKJA4YbyL%z9dd2JP;jM+34&F$-N|w}a3ym5=;;{&9#5XGs8E-*CV4mAMS5Nb=OraR zP5NoBH;!U#80wN@iHYXLau}R*u3H+CCa0W|dyzejWVP#5tk`X+%<3Bz&>HIdWByr^ zUbdyt$$CY~vQfSOE6-K57AC(?j7sEhOYnqOnjcqVk3P=G=Z9Jcb@wHUj(ghB&yK9w z0oAm@i&77nu9~^CNtP7j3tzlYaLiU_X~!TfEDhvs!a*gomrrz$Ail_mALY)A;}#CR zfXH*ad-0&Qz=IWcfXi>z5pOX~-K<^xmMW(vJR$cXa$?b^s|US0+w-zMQeyFBrxI8!ulC=1NE4N0=gb^nO3}f``X2FswQ3J#wgOpN}4($7Moz^(Cn+ zN?@&NDO0IkHKFC}pBg_~&HJpOrF~cbl($mH(WrWx4-}ygb zTR~rHv#{%S9}{PtKG2plL#s6mo#iVL%JH<87q{lruYl>@@;lJDwwKV+)|KmwL`vc0 ziq_N8IR&9_X4IZ`;1tvfZ-2Jk+Su|=t-mW00D21x-j1DG!$(WP-dA}-fzESlz(Jhs zjpm~c&-j@}zqmXpO0x=Z{LUidu{ZiT;=XEzp+OjyxL^*BF(bf<0{mA|!N<~$2}t_}WbpVX+YzsNm>bi_g6H%~J0o3O=7>9I1IfMpZ+dLzXK+LE+oLg};!W1lmdtjRpy z_B8w18`{>0MV|w02SkPH7HO<|@r=K9B!Bd?Deliq21_UJn4a4FvK1@yDf#l4^Y2l(uy{&QMf(aPSc&o0}xwk9%U3DVO_uG5_u z1S0||d`lY|QAn!<<8%C~UquDB>uS1TB&K@Xk_@xL%x$irC1n$ zoa)()*IOuq{A#Giiaw=uEl5#*@@>BO_4qFGR_Rr~bIwtXwhI}Fwg-#55Nu4ILQIyd zOCS&DiHAA5kH*-f>IhD&^WPt_QG50ML)4t!l1<|}9m8rg^cWm-n~c|qpX*oyM$*WZ zr0J-ag|F08Z)kCds=F*JDHje(VXs_um_rLp3=EtRm@T)v7tE_h-!VAv(-S%|CU0Ju zVVa0+p8(&U2VPn&)-%O=#wzrsfFF`Zd5A^AB2gozHZBeEORsbNbEM8UQI9(BWhI-K zVFO`@UM~QYm;iuC;GtK&s)}b-*}uGs{O;Aj+t154%+1Y4{a>czbQTV3O7FlJ^>_`n z5hRcv!{&|a;%ijn7SH^k@81boOUYRI=;i$uetWn1T^tLM_lg90m_7$6lQ!!QXnU%AAqcxOCMbJEj&lTENMgj4b(0+=%_ZFbS>7VJ*8kjXj z42C|qV;Dji|8_fVrLW)5muw)ER~?(!qRIEioxKXJAZ!h-(KN!WYQ5u7M*&N7@hs{+iOpE=1s 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 0000000000000000000000000000000000000000..4c8bf3db8f496f94424a9fd10a77ece3b3caaa29 GIT binary patch literal 398720 zcmeIu`F{w60s!!>c_w6z$#@ht*GR4&vdI;5JZ9$MrB7_mK8iMPxlN9kqm6j3jX9&^ zA+^Ml`&=~Y6(X6r(q1{zki9?R{rdg>3E!IwYZoq>a`Ts^H=;-OI+1}7o88R zy|7JA!1Rhu!{?o@oOdpyLhz2@;(&j>csL<%&a#%_9WLI^nU>KhqjI~x*+E~_ifOxa z^MYiP@vig;EReEjheX3dTl;oHdAx%CX9$9$i!SP!8HzHe?Jysm>{E>E70~Y?N zTixLaefLe<6P7(BJt-ot%X`HEKgE{l-e6eKsXkfXZCVkzV%g>M*KJ%xwMj?8^OvoNUM$6qJC()#F##Qf>8WslEaojP%N zTE7Oh$Jc0oaL2eKSC@sf*z*0BR+$k)AN`&XS!ed)S()AIB|I_Uol$8On{;?^>ak-7 zTg+Yh@|me;*Dr6-H?(1!i<9;bYx;BFf*-23$$2L`^mKURA1>rX<%gC^4zJiW^!=<$ zQK#3{T-{}MWMcJ0&3jFJKjpwIL+u>)~lB!OOPh*T4AVj!PR~i=KO_>Yj+1rJ}<_?~hpW0^C#?alPrZxMuRn?>WS5}Led#EtHXy?$KaXWjID)G_8`w6LGHD2B} zU~#YB^NIuRU%$1t*68z5!(K?+h9~3!hOl z+hQw6@4K?HAieV0jZs75d#((axp?xmYEKP)=gpH(=H6*_y=P3`x2b!|buZVYASSKl z{KH8(iG7ONKYe_7tre;5@kimRj1zS+;w~5u$&UBI?ju)RprX}Vb4C;v1#eHX8-JQ z==szMr!UQF&_DI%H^+V%n6zbXQ0dFh#=bHA&gu$#G6vqycvLy+)1Iq0=YG)TeD%8z z-&?TnmF*uiKNgM_BAy=s5>>hkVqy4HRsH+l2! zJ@FN?iY}L4KY#wrI{n8?zSc88Z+_9C#~W|_sO!led#^2Z;%222Vezn{R%1`J~WK$CtQW)MrWS_2C6U3)W=s585$)blk|F8Xb8%_=nKI!~hH! zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* V1`HT5V8DO@0|pEjFz|m4{11jIha&(0 literal 0 HcmV?d00001 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..32d891f9c7 --- /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..b4dc450098 --- /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..4c8e83a07f --- /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..2b3d2ba7f7 --- /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..6b57ef3269 --- /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..0c9245b8f4 --- /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..f47232bf2e --- /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..900a3ad358 --- /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..c3c8a3f27d --- /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/group12/446031103/src/com/coderising/download/FileDownloaderTest.java b/group06/547958234/src/com/coderising/download/FileDownloaderTest.java similarity index 100% rename from group12/446031103/src/com/coderising/download/FileDownloaderTest.java rename to group06/547958234/src/com/coderising/download/FileDownloaderTest.java 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..0957eaf7f4 --- /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..1551a80b3d --- /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..ce045393b1 --- /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..bf9807b307 --- /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..36a9d2ce15 --- /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..172371dd55 --- /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/group15/1521_653895972/src/com/coding/coderising/litestruts/StrutsTest.java b/group06/547958234/src/com/coderising/litestruts/StrutsTest.java similarity index 96% rename from group15/1521_653895972/src/com/coding/coderising/litestruts/StrutsTest.java rename to group06/547958234/src/com/coderising/litestruts/StrutsTest.java index 8699cc3eca..b8c81faf3c 100644 --- a/group15/1521_653895972/src/com/coding/coderising/litestruts/StrutsTest.java +++ b/group06/547958234/src/com/coderising/litestruts/StrutsTest.java @@ -1,11 +1,11 @@ -package com.coding.coderising.litestruts; - -import org.junit.Assert; -import org.junit.Test; +package com.coderising.litestruts; import java.util.HashMap; import java.util.Map; +import org.junit.Assert; +import org.junit.Test; + diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/View.java b/group06/547958234/src/com/coderising/litestruts/View.java similarity index 100% rename from group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/View.java rename to group06/547958234/src/com/coderising/litestruts/View.java 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..e084ee3109 --- /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..39793ef0c6 --- /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..7e98354f3b --- /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..17ca1ce521 --- /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..8639cf4fa1 --- /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..5f8f4ea1fd --- /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..6aa0e8237f --- /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..50ed931c8b --- /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..47f348cd8c --- /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..6ae4adeed6 --- /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..97e286827f --- /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..734649f37a --- /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..dcdbe226ed --- /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..0bd53fea93 --- /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..cbe732d83f --- /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..3e9678cbd8 --- /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..b8c81faf3c --- /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..07df2a5dab --- /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/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..fe086e2d67 --- /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..843e5a06a2 --- /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..55cf214fe2 --- /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..86c0e63054 --- /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..50eb1be6fa --- /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 46d6fa61e40039963836bc89af32088aaf3e1bc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10920 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 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/shoppingcart.data b/group09/41689722.eulerlcs/2.code/jmr-11-challenge/data/shoppingcart/shoppingcart.data new file mode 100644 index 0000000000000000000000000000000000000000..336fd732b4dcf94a212cb3a8f2718aca7a10584b GIT binary patch literal 131 zcmZ=T{#&s4I+ra20|O5Ok5^(@qC$vnaYklQiG%X5hwke{s(~^b3>;t?-_mpkeYhwu zgRo0!cB+C`X?l82W?s62OMXsHu>=3>R=FL4Z-Cllq1pm6^Bjb~9_o+L_y!a;V&DTC O=ABxp;GB_|nFj!(-zjkb literal 0 HcmV?d00001 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/group17/1264835468/src/assignment2_26/LoginAction.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/LoginAction.java similarity index 91% rename from group17/1264835468/src/assignment2_26/LoginAction.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/LoginAction.java index 3101d322b8..5f41f42c62 100644 --- a/group17/1264835468/src/assignment2_26/LoginAction.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/LoginAction.java @@ -1,42 +1,42 @@ -package assignment2_26; - -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * - * @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; - } -} +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/group17/1264835468/src/assignment2_26/View.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/View.java similarity index 87% rename from group17/1264835468/src/assignment2_26/View.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/View.java index e96197fad6..f1e7fcfa19 100644 --- a/group17/1264835468/src/assignment2_26/View.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coderising/litestruts/View.java @@ -1,26 +1,26 @@ -package assignment2_26; - -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; - } -} +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/group15/1513_121469918/HomeWork01/src/coding/BinaryTreeNode.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/BinaryTreeNode.java similarity index 54% rename from group15/1513_121469918/HomeWork01/src/coding/BinaryTreeNode.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/BinaryTreeNode.java index 8e40fa1d90..2f944d3b91 100644 --- a/group15/1513_121469918/HomeWork01/src/coding/BinaryTreeNode.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/BinaryTreeNode.java @@ -1,6 +1,7 @@ -package coding; +package com.coding.basic; public class BinaryTreeNode { + private Object data; private BinaryTreeNode left; private BinaryTreeNode right; @@ -30,23 +31,6 @@ public void setRight(BinaryTreeNode right) { } public BinaryTreeNode insert(Object o) { - // жϵǰڵԪ - if (data == null) { - setData(o); - } else { - Integer i = (Integer) o; - // ǰڵжҽڵ - if (i.compareTo((Integer) data) == -1) { - if(right == null) - right = new BinaryTreeNode(); - return right.insert(i); - } else if (i.compareTo((Integer) data) == 1) { - if(left == null) - left = new BinaryTreeNode(); - return left.insert(i); - } - return null; - } return null; } diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Iterator.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Iterator.java similarity index 81% rename from group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Iterator.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Iterator.java index f5cf74673d..f30dfc8edf 100644 --- a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Iterator.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/main/java/com/coding/basic/Iterator.java @@ -2,6 +2,7 @@ public interface Iterator { public boolean hasNext(); + public Object next(); - public Object remove(); + } 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/group17/1264835468/src/assignment2_26/StrutsTest.java b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts/StrutsTest.java similarity index 94% rename from group17/1264835468/src/assignment2_26/StrutsTest.java rename to group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts/StrutsTest.java index f47410209b..f2426db6ea 100644 --- a/group17/1264835468/src/assignment2_26/StrutsTest.java +++ b/group09/41689722.eulerlcs/2.code/jmr-51-liuxin-question/src/test/java/com/coderising/litestruts/StrutsTest.java @@ -1,38 +1,38 @@ -package assignment2_26; - -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")); - } -} +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-170226-collection/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/pom.xml deleted file mode 100644 index 90b5cc3818..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/pom.xml +++ /dev/null @@ -1,27 +0,0 @@ - - 4.0.0 - - com.github.eulerlcs - jmr-02-parent - 0.0.1-SNAPSHOT - ../jmr-02-parent/pom.xml - - jmr-61-170226-collection - eulerlcs master java road collection - - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - junit - junit - - - \ No newline at end of file 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-170226-collection/src/main/resources/log4j.xml deleted file mode 100644 index 831b8d9ce3..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170226-collection/src/main/resources/log4j.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/data/struts.xml b/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/data/struts.xml deleted file mode 100644 index a7a77b73df..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/data/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml deleted file mode 100644 index 6ce14ac574..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - 4.0.0 - - com.github.eulerlcs - jmr-02-parent - 0.0.1-SNAPSHOT - ../jmr-02-parent/pom.xml - - jmr-61-170305-litestruts - eulerlcs master java road lite struts - - - - commons-digester - commons-digester - - - org.projectlombok - lombok - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - junit - junit - - - com.github.stefanbirkner - system-rules - - - \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/resources/log4j.xml b/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/resources/log4j.xml deleted file mode 100644 index 831b8d9ce3..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170305-litestruts/src/main/resources/log4j.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml b/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml deleted file mode 100644 index 8f300f8306..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - 4.0.0 - - com.github.eulerlcs - jmr-02-parent - 0.0.1-SNAPSHOT - ../jmr-02-parent/pom.xml - - jmr-61-170312-multiThreadDownload - eulerlcs master java road - download file by multiple thread - - - - commons-digester - commons-digester - - - org.projectlombok - lombok - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - junit - junit - - - com.github.stefanbirkner - system-rules - - - \ 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/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-170312-multiThreadDownload/src/main/resources/log4j.xml b/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/resources/log4j.xml deleted file mode 100644 index 831b8d9ce3..0000000000 --- a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/resources/log4j.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file 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/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-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-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-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-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/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Iterator.java b/group09/790466157/src/com/coderising/linkedlist/Iterator.java similarity index 70% rename from group01/1814014897/zhouhui/src/week01/BasicDataStructure/Iterator.java rename to group09/790466157/src/com/coderising/linkedlist/Iterator.java index 0ad3fff8f3..b09016ee94 100644 --- a/group01/1814014897/zhouhui/src/week01/BasicDataStructure/Iterator.java +++ b/group09/790466157/src/com/coderising/linkedlist/Iterator.java @@ -1,4 +1,4 @@ -package week01.BasicDataStructure; +package com.coderising.linkedlist; public interface Iterator { public boolean hasNext(); 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..95dc7ca88f --- /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/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..5910b4a15b --- /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..5efe4cbc2a --- /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..f43bfbdbae --- /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/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java b/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java index b4d218399f..3c13facd32 100644 --- a/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java +++ b/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java @@ -1,8 +1,6 @@ package com.coderising.download; import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; @@ -31,35 +29,6 @@ public DownloadThread(String downloadPath, Connection conn, int startPos, this.endPos = endPos; } - /** - * 这种操作存在弊端, - * 若文件过大,调用conn.read读取过程中程序中断 - * 将无法缓存任何数据 - */ - /*public void run() { - - try { - - //请求服务器下载部分文件 指定文件的位置 读取指定位子的字节 - byte[] buffer = conn.read(startPos, endPos); - //随机访问文件流 - RandomAccessFile raf = new RandomAccessFile(tempFile, "rwd"); - //随机写文件的时候从哪个位置开始写 - raf.seek(startPos);//定位文件 - //写文件 - raf.write(buffer); - raf.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (conn != null) { - conn.close(); - } - } - }*/ - public void run() { try { @@ -75,8 +44,8 @@ public void run() { tempFile = file; //获取指定文件段的下载流 InputStream in = conn.getDownloadStream(startPos, endPos); - if(in == null){ - return; + if(in == null){//重新请求连接 + run(); } //随机访问文件流 RandomAccessFile raf = new RandomAccessFile(tempFile, "rwd"); @@ -90,10 +59,9 @@ public void run() { downloadSize += length; } raf.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + } catch (Exception e) { + run(); + e.printStackTrace(); } finally { if (conn != null) { conn.close(); diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java b/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java index cb84d148c7..721f2c77e0 100644 --- a/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java +++ b/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java @@ -31,18 +31,7 @@ public void execute(){ conn = cm.open(this.url); int length = conn.getContentLength(); //分配下载块 - int blockSize = length / threadNum; - DownloadThread[] threads = new DownloadThread[threadNum]; - for (int thread = 1; thread <= threadNum; thread++) { - int startIndex = (thread - 1) * blockSize; - int endIndex = thread * blockSize-1; - if (thread == threadNum) {//最后一个线程下载的长度 - endIndex = length; - } - DownloadThread thr = new DownloadThread(downloadPath,cm.open(this.url),startIndex,endIndex); - threads[thread-1] = thr; - thr.start(); - } + DownloadThread[] threads = assignDownloadPart(length); //判断所有线程是否下载完成 new NotifyCaller(listener,threads,length).start(); @@ -54,6 +43,29 @@ public void execute(){ } } } + + /** + * 分配下载块并启动下载 + * @param length + * @return + * @throws ConnectionException + */ + private DownloadThread[] assignDownloadPart(int length) + throws ConnectionException { + int blockSize = length / threadNum; + DownloadThread[] threads = new DownloadThread[threadNum]; + for (int thread = 1; thread <= threadNum; thread++) { + int startIndex = (thread - 1) * blockSize; + int endIndex = thread * blockSize-1; + if (thread == threadNum) {//最后一个线程下载的长度 + endIndex = length; + } + DownloadThread thr = new DownloadThread(downloadPath,cm.open(this.url),startIndex,endIndex); + threads[thread-1] = thr; + thr.start(); + } + return threads; + } public void setListener(DownloadListener listener) { this.listener = listener; diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java b/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java index 03f4149688..df49a92a07 100644 --- a/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java +++ b/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java @@ -65,7 +65,7 @@ private String getDownloadSpeed(int timeDiff){ if(num==null||num.isEmpty()){ num = "0"; } - return num+"M/s"; + return num+"Mb/s"; } /** diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java b/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java index ec8e503fe9..8f5a0a8757 100644 --- a/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java +++ b/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java @@ -7,7 +7,7 @@ import com.coderising.download.api.Connection; -public class ConnectionImpl implements Connection{ +class ConnectionImpl implements Connection{ /*http连接*/ private HttpURLConnection httpConnection; @@ -18,19 +18,8 @@ public class ConnectionImpl implements Connection{ @Override public byte[] read(int startPos, int endPos) throws IOException { - byte[] data = null; InputStream is = getDownloadStream(startPos,endPos); - if(is !=null){ - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length = -1; - while ((length = is.read(buffer)) != -1) { - baos.write(buffer, 0, length); - } - baos.flush(); - data = baos.toByteArray(); - } - return data; + return inputStremCovertToArray(is); } @Override @@ -53,6 +42,27 @@ public void close() { httpConnection.disconnect(); } + /** + * 将输入流转换为byte数组 + * @param is + * @return + * @throws IOException + */ + private byte[] inputStremCovertToArray(InputStream is) throws IOException{ + + byte[] data = null; + if(is !=null){ + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length = -1; + while ((length = is.read(buffer)) != -1) { + baos.write(buffer, 0, length); + } + baos.flush(); + data = baos.toByteArray(); + } + return data; + } public void setHttpConnection(HttpURLConnection httpConnection) { this.httpConnection = httpConnection; } diff --git a/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..e005c00c5c --- /dev/null +++ b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,33 @@ +package com.coderising.jvm.loader; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + File clzFile = ClassFileLoaderUtil.getClzFile(clzPaths,className); + + return ClassFileLoaderUtil.readClz(clzFile); + + } + + public void addClassPath(String path) { + + this.clzPaths.add(path); + } + + public String getClassPath(){ + + StringBuffer buff = new StringBuffer(); + for (String str : clzPaths) { + buff.append(str+";"); + } + return buff.substring(0, buff.length()-1); + } + +} diff --git a/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java new file mode 100644 index 0000000000..254490ed42 --- /dev/null +++ b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java @@ -0,0 +1,71 @@ +package com.coderising.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.List; + +public class ClassFileLoaderUtil { + + /** + * 根据类完整包名与classPath获取类class文件 + * @return + */ + public static File getClzFile(List clzPaths ,String className){ + + File clazFile = null; + //将com.zj.className 转化为 com\\zj\\className.class; + if(className!=null){ + className = className.replace(".", "\\")+".class"; + } + //寻找文件所在目录 + for (String clzPath : clzPaths) { + clazFile = new File(clzPath+"\\"+className); + if(clazFile.exists()){ + break; + } + } + return clazFile; + } + + /** + * 读取文件并返回该文件的字节数组 + * @param clzFile + * @return + */ + public static byte[] readClz(File file){ + + byte[] data = null; + InputStream is = null; + ByteArrayOutputStream baos = null; + try { + is = new FileInputStream(file); + if(is !=null){ + baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length = -1; + while ((length = is.read(buffer)) != -1) { + baos.write(buffer, 0, length); + } + baos.flush(); + data = baos.toByteArray(); + } + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + if(baos!=null){ + baos.close(); + } + if(is!=null){ + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return data; + } +} diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java b/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java index 3449517197..202aa4f54a 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java +++ b/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java @@ -1,5 +1,7 @@ package com.coding.basic; +import com.coding.basic.array.ArrayList; + public class BinaryTree { //根节点 diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java b/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java index e29ff65ddf..0b61390a85 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java +++ b/group12/2258659044/zj-2017/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 element = new LinkedList(); diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java b/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java index 03709097e5..97390f0133 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java +++ b/group12/2258659044/zj-2017/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/group12/2258659044/zj-2017/src/com/coding/basic/ArrayList.java b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayList.java similarity index 94% rename from group12/2258659044/zj-2017/src/com/coding/basic/ArrayList.java rename to group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayList.java index f1fbf7e8b1..91fe3cd6fd 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/ArrayList.java +++ b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayList.java @@ -1,100 +1,103 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -public class ArrayList implements List { - - private int size = 0; - /*扩容因子*/ - private static final int GENE = 10; - - private Object[] elementData = new Object[10]; - /*扩容引用*/ - private Object[] newElementData; - - public void add(Object o){ - grow(); - elementData[size] = o; - size ++; - } - public void add(int index, Object o){ - - if(index<0||index>size){ - throw new IndexOutOfBoundsException("Index: "+index+",Size:"+size); - } - grow(); - if(indexsize){ - throw new IndexOutOfBoundsException("Index: "+index+",Size:"+size); - } - return elementData[index]; - } - - public Object remove(int index){ - - Object o = elementData[index]; - System.arraycopy(elementData, index+1, elementData, index, size-(index+1)); - size --; - return o; - } - - public int size(){ - return size; - } - - public Object[] toArray(){ - Object[] objArr = new Object[size]; - System.arraycopy(elementData, 0, objArr, 0, size); - return objArr; - } - - /** - * 扩容,扩容因子为10 - */ - private void grow(){ - - if(size>=elementData.length){//长度不够需要扩容 - newElementData = new Object[size+GENE]; - System.arraycopy(elementData, 0, newElementData, 0, elementData.length); - elementData = newElementData; - } - } - - - public Iterator iterator(){ - - return new Itr(); - } - - private class Itr implements Iterator{ - - int cursor; - @Override - public boolean hasNext() { - return cursor != ArrayList.this.size; - } - - @Override - public Object next() { - - int i = this.cursor; - if (i >= ArrayList.this.size){ - throw new NoSuchElementException(); - } - this.cursor = (i + 1); - return ArrayList.this.elementData[i]; - } - - } +package com.coding.basic.array; + +import java.util.NoSuchElementException; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class ArrayList implements List { + + private int size = 0; + /*扩容因子*/ + private static final int GENE = 10; + + private Object[] elementData = new Object[10]; + /*扩容引用*/ + private Object[] newElementData; + + public void add(Object o){ + grow(); + elementData[size] = o; + size ++; + } + public void add(int index, Object o){ + + if(index<0||index>size){ + throw new IndexOutOfBoundsException("Index: "+index+",Size:"+size); + } + grow(); + if(indexsize){ + throw new IndexOutOfBoundsException("Index: "+index+",Size:"+size); + } + return elementData[index]; + } + + public Object remove(int index){ + + Object o = elementData[index]; + System.arraycopy(elementData, index+1, elementData, index, size-(index+1)); + size --; + return o; + } + + public int size(){ + return size; + } + + public Object[] toArray(){ + Object[] objArr = new Object[size]; + System.arraycopy(elementData, 0, objArr, 0, size); + return objArr; + } + + /** + * 扩容,扩容因子为10 + */ + private void grow(){ + + if(size>=elementData.length){//长度不够需要扩容 + newElementData = new Object[size+GENE]; + System.arraycopy(elementData, 0, newElementData, 0, elementData.length); + elementData = newElementData; + } + } + + + public Iterator iterator(){ + + return new Itr(); + } + + private class Itr implements Iterator{ + + int cursor; + @Override + public boolean hasNext() { + return cursor != ArrayList.this.size; + } + + @Override + public Object next() { + + int i = this.cursor; + if (i >= ArrayList.this.size){ + throw new NoSuchElementException(); + } + this.cursor = (i + 1); + return ArrayList.this.elementData[i]; + } + + } } \ No newline at end of file diff --git a/group12/2258659044/zj-2017/src/com/coderising/array/ArrayUtil.java b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayUtil.java similarity index 94% rename from group12/2258659044/zj-2017/src/com/coderising/array/ArrayUtil.java rename to group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayUtil.java index 3f41a350e8..9cb55f0f53 100644 --- a/group12/2258659044/zj-2017/src/com/coderising/array/ArrayUtil.java +++ b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayUtil.java @@ -1,248 +1,247 @@ -package com.coderising.array; - -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 length = origin.length; - int[] temp = new int[length]; - for (int i = 0; i < length; i++) { - temp[i] = origin[length-1-i]; - } - System.arraycopy(temp, 0, origin, 0, length); - } - - /** - * 现在有如下的一个数组: 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 length = oldArray.length; - int[] tempArr = new int[length]; - int j = 0; - int zeroNum = 0;//储存0的个数 - for (int i = 0; i < length; i++) { - if(oldArray[i]!=0){ - tempArr[j] = oldArray[i]; - j ++; - }else{ - zeroNum ++; - } - } - //删除数组尾端的0 - int[] newArray = new int[length-zeroNum]; - System.arraycopy(tempArr, 0, newArray, 0, length-zeroNum); - 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 length1 = array1.length; - int length2 = array2.length; - int[] array3 = new int[length1 + length2]; - //将array1、array2的值加入array3中 - System.arraycopy(array1, 0, array3, 0, length1); - System.arraycopy(array2, 0, array3, length1, length2); - int length = array3.length; - int temp; - //将array3冒泡排序 - for (int i = 0; i < length; i++) { - for (int j = 0; j < length - i; j++) { - if(array3[i]>array3[j+i]){ - temp = array3[i]; - array3[i] = array3[j+i]; - array3[j+i] = temp; - } - } - } - return duplicate(array3); - } - - /** - *去重 - */ - private int[] duplicate(int[] array){ - - for (int i = 1; i < array.length; i++) { - if(array[i-1]==array[i]){ - array[i] = 0; - } - } - return removeZero(array); - } - - /** - * 位图法合并 - * @param array1 - * @param array2 - * @return - */ - public int[] merge2(int[] array1, int[] array2){ - - int bitSize = 0; - int a = array1[array1.length-1] ; - int b = array2[array2.length-1]; - bitSize =(a>b)?a:b; - boolean[] bitmap = new boolean[bitSize+1]; - for (int i = 0; i < array1.length; i++) { - bitmap[array1[i]]=true; - } - for (int i = 0; i < array2.length; i++) { - bitmap[array2[i]]=true; - } - - ArrayList ls = new ArrayList(); - for (int i = 0; i < bitmap.length; i++) { - if(bitmap[i]==true){ - ls.add(i); - } - } - return objList2int(ls); - } - - /** - * 把一个已经存满数据的数组 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[] array = {}; - if(max <= 1)return array; - //生成 斐波那契数列的ArrayList集合 - ArrayList ls = new ArrayList(); - ls.add(1);ls.add(1); - int next;int i = 1; - while(true){ - next = (int)ls.get(i) +(int)ls.get(i-1); - if(next >= max){ - break; - } - ls.add(next); - i ++; - } - return objList2int(ls); - } - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public int[] getPrimes(int max){ - - ArrayList primesList = new ArrayList(); - boolean flag; - for (int i = 2; i < max; i++) { - flag = false; - for (int j = 2; j <= Math.sqrt(i); j++) { - if (i % j == 0) { - flag =true; - break; - } - } - if(!flag){ - primesList.add(i); - } - } - return objList2int(primesList); - } - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * @param max - * @return - */ - public int[] getPerfectNumbers(int max){ - - int temp; - ArrayList perfectList = new ArrayList(); - for (int i = 6; i <= max; i++) { - temp = 0; - for (int j = 1; j <= (i/2); j++) { - if(i%j == 0){ - temp += j; - } - } - if(temp == i){ - perfectList.add(i); - } - } - return objList2int(perfectList); - } - - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" - * @param array - * @param s - * @return - */ - public String join(int[] array, String seperator){ - - StringBuilder str = new StringBuilder(); - for (int i = 0; i < array.length; i++) { - str.append(array[i]+seperator); - } - return str.substring(0, str.lastIndexOf(seperator)); - } - - /** - * 将存储int数据的ArrayList转换为int数组 - * @param ls - * @return - */ - public int[] objList2int(ArrayList ls){ - - Object[] objArr = ls.toArray(); - int[] array = new int[ls.size()]; - for (int i = 0; i < ls.size(); i++) { - array[i] = (int) objArr[i]; - } - return array; - } - -} +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 length = origin.length; + int[] temp = new int[length]; + for (int i = 0; i < length; i++) { + temp[i] = origin[length-1-i]; + } + System.arraycopy(temp, 0, origin, 0, length); + } + + /** + * 现在有如下的一个数组: 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 length = oldArray.length; + int[] tempArr = new int[length]; + int j = 0; + int zeroNum = 0;//储存0的个数 + for (int i = 0; i < length; i++) { + if(oldArray[i]!=0){ + tempArr[j] = oldArray[i]; + j ++; + }else{ + zeroNum ++; + } + } + //删除数组尾端的0 + int[] newArray = new int[length-zeroNum]; + System.arraycopy(tempArr, 0, newArray, 0, length-zeroNum); + 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 length1 = array1.length; + int length2 = array2.length; + int[] array3 = new int[length1 + length2]; + //将array1、array2的值加入array3中 + System.arraycopy(array1, 0, array3, 0, length1); + System.arraycopy(array2, 0, array3, length1, length2); + int length = array3.length; + int temp; + //将array3冒泡排序 + for (int i = 0; i < length; i++) { + for (int j = 0; j < length - i; j++) { + if(array3[i]>array3[j+i]){ + temp = array3[i]; + array3[i] = array3[j+i]; + array3[j+i] = temp; + } + } + } + return duplicate(array3); + } + + /** + *去重 + */ + private int[] duplicate(int[] array){ + + for (int i = 1; i < array.length; i++) { + if(array[i-1]==array[i]){ + array[i] = 0; + } + } + return removeZero(array); + } + + /** + * 位图法合并 + * @param array1 + * @param array2 + * @return + */ + public int[] merge2(int[] array1, int[] array2){ + + int bitSize = 0; + int a = array1[array1.length-1] ; + int b = array2[array2.length-1]; + bitSize =(a>b)?a:b; + boolean[] bitmap = new boolean[bitSize+1]; + for (int i = 0; i < array1.length; i++) { + bitmap[array1[i]]=true; + } + for (int i = 0; i < array2.length; i++) { + bitmap[array2[i]]=true; + } + + ArrayList ls = new ArrayList(); + for (int i = 0; i < bitmap.length; i++) { + if(bitmap[i]==true){ + ls.add(i); + } + } + return objList2int(ls); + } + + /** + * 把一个已经存满数据的数组 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[] array = {}; + if(max <= 1)return array; + //生成 斐波那契数列的ArrayList集合 + ArrayList ls = new ArrayList(); + ls.add(1);ls.add(1); + int next;int i = 1; + while(true){ + next = (int)ls.get(i) +(int)ls.get(i-1); + if(next >= max){ + break; + } + ls.add(next); + i ++; + } + return objList2int(ls); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + + ArrayList primesList = new ArrayList(); + boolean flag; + for (int i = 2; i < max; i++) { + flag = false; + for (int j = 2; j <= Math.sqrt(i); j++) { + if (i % j == 0) { + flag =true; + break; + } + } + if(!flag){ + primesList.add(i); + } + } + return objList2int(primesList); + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + + int temp; + ArrayList perfectList = new ArrayList(); + for (int i = 6; i <= max; i++) { + temp = 0; + for (int j = 1; j <= (i/2); j++) { + if(i%j == 0){ + temp += j; + } + } + if(temp == i){ + perfectList.add(i); + } + } + return objList2int(perfectList); + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + + StringBuilder str = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + str.append(array[i]+seperator); + } + return str.substring(0, str.lastIndexOf(seperator)); + } + + /** + * 将存储int数据的ArrayList转换为int数组 + * @param ls + * @return + */ + public int[] objList2int(ArrayList ls){ + + Object[] objArr = ls.toArray(); + int[] array = new int[ls.size()]; + for (int i = 0; i < ls.size(); i++) { + array[i] = (int) objArr[i]; + } + return array; + } + +} diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java b/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..b8a24f2f34 --- /dev/null +++ b/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,163 @@ +package com.coding.basic.linklist; + + +/** + * 用双向链表实现LRU算法 + * @author ZJ + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + Object obj; + + Node() { + } + } + + 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(Object obj) { + + if(obj == null){ + return; + } + Node node = getNode(obj); + if(node!=null){ + move2head(node); + }else{ + refresh(obj); + } + } + + /** + * 刷新LRU队列 + * @param obj + */ + private void refresh(Object obj) { + //添加元素 + if(size0){ - head.next = secondNode; - } - size ++; - } - - public void addLast(Object o){ - add(o); - } - - public Object removeFirst(){ - - return remove(0); - } - - public Object removeLast(){ - - return remove(size-1); - } - public Iterator iterator(){ - return new Itr(); - } - - private class Itr implements Iterator{ - - int cursor; - @Override - public boolean hasNext() { - return cursor != LinkedList.this.size; - } - - @Override - public Object next() { - - int i = this.cursor; - if (i >= LinkedList.this.size){ - throw new NoSuchElementException(); - } - this.cursor = (i + 1); - return LinkedList.this.get(i); - } - - } - - /** - * 获取指定的节点 - * @return - */ - private Node getPointNode(int index){ - - if(index<0||index>size){ - throw new IndexOutOfBoundsException("Index: "+index+",Size:"+size+""); - } - Node node = head; - for (int i = 0; i < index; i++) { - node = node.next; - } - return node; - } - - private static class Node{ - Object data; - Node next; - - } - - /** - * 把该链表逆置 - * 例如链表为 3->7->10 , 逆置后变为 10->7->3 - */ - public void reverse(){ - - Stack stack = new Stack(); - Node node; - //缓存原链表数据 - for (node = head; node!=null;node = node.next) { - stack.push(node.data); - } - //重新赋值 - for (node = head; node!=null;node = node.next) { - node.data = stack.pop(); - } - } - - /** - * 删除一个单链表的前半部分 - * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 - * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 - */ - public void removeFirstHalf(){ - int newSize = size/2; - head = getPointNode(newSize); - size = size%2>0?newSize+1:newSize; - } - - /** - * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 - * @param i - * @param length - */ - public void remove(int i, int length){ - - if(i==0){ - if(length101->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++) { - array[i] = (int) get((int)list.get(i)); - } - return array; - } - - /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 从当前链表中中删除在list中出现的元素 - * @param list - */ - - public void subtract(LinkedList list){ - for (int i = 0; i < size; i++) { - for (int j = 0; j < list.size(); j++) { - if(get(i).equals(list.get(j))){ - remove(i); - i--; - } - } - } - } - - /** - * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) - */ - public void removeDuplicateValues(){ - - for (int i = 0; i < size-1; i++) { - if(get(i).equals(get(i+1))){ - remove(i); - i --; - } - } - } - - /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) - * @param min - * @param max - */ - public void removeRange(int min, int max){ - - for (int i = 0; i < size; i++) { - if((int)get(i)>min&&(int)get(i)0){ + head.next = secondNode; + } + size ++; + } + + public void addLast(Object o){ + add(o); + } + + public Object removeFirst(){ + + return remove(0); + } + + public Object removeLast(){ + + return remove(size-1); + } + public Iterator iterator(){ + return new Itr(); + } + + private class Itr implements Iterator{ + + int cursor; + @Override + public boolean hasNext() { + return cursor != LinkedList.this.size; + } + + @Override + public Object next() { + + int i = this.cursor; + if (i >= LinkedList.this.size){ + throw new NoSuchElementException(); + } + this.cursor = (i + 1); + return LinkedList.this.get(i); + } + + } + + /** + * 获取指定的节点 + * @return + */ + private Node getPointNode(int index){ + + if(index<0||index>size){ + throw new IndexOutOfBoundsException("Index: "+index+",Size:"+size+""); + } + Node node = head; + for (int i = 0; i < index; i++) { + node = node.next; + } + return node; + } + + private static class Node{ + Object data; + Node next; + + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + Stack stack = new Stack(); + Node node; + //缓存原链表数据 + for (node = head; node!=null;node = node.next) { + stack.push(node.data); + } + //重新赋值 + for (node = head; node!=null;node = node.next) { + node.data = stack.pop(); + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + int newSize = size/2; + head = getPointNode(newSize); + size = size%2>0?newSize+1:newSize; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + + if(i==0){ + if(length101->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++) { + array[i] = (int) get((int)list.get(i)); + } + return array; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * @param list + */ + + public void subtract(LinkedList list){ + for (int i = 0; i < size; i++) { + for (int j = 0; j < list.size(); j++) { + if(get(i).equals(list.get(j))){ + remove(i); + i--; + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + for (int i = 0; i < size-1; i++) { + if(get(i).equals(get(i+1))){ + remove(i); + i --; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + + for (int i = 0; i < size; i++) { + if((int)get(i)>min&&(int)get(i)parameters){ if(actionName == null || parameters == null) return null; List actions = null; try { - File xmlfile = new File("D:\\5Java\\coding2017\\group12\\247565311\\week2\\struts.xml"); + File xmlfile = new File(System.getProperty("user.dir")+"\\bin\\week2\\struts.xml"); Document doc = new SAXReader().read(xmlfile); Element root = doc.getRootElement(); actions = root.elements(); diff --git a/group12/247565311/week3/DownloadThread.java b/group12/247565311/week3/DownloadThread.java index 3271ba2e99..2670bef00b 100644 --- a/group12/247565311/week3/DownloadThread.java +++ b/group12/247565311/week3/DownloadThread.java @@ -1,24 +1,31 @@ package week3; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; import week3.api.Connection; public class DownloadThread extends Thread{ Connection conn; + CyclicBarrier barrier; int startPos; int endPos; String path = ""; - public DownloadThread( Connection conn, int startPos, int endPos,String filepath){ + int step = 1024*200; // ÿ200kдһļ + public DownloadThread(CyclicBarrier _barrier, Connection conn, int startPos, int endPos,String filepath){ this.conn = conn; this.startPos = startPos; this.endPos = endPos; this.path = filepath; + this.barrier = _barrier; } public void run(){ // ȡصֽ飬дļעһ̳߳ @@ -27,27 +34,28 @@ public void run(){ // connectȡֽ飬ûֽˣͱʾⲿ // filepathдļ if(conn == null) return; - ByteBuffer buffer = ByteBuffer.allocate(endPos-startPos); - Path filepath = Paths.get(path); - - if(filepath == null) return; int curEndPos = startPos; - // while(curEndPos endPos) + curEndPos += step; + if (curEndPos > endPos) curEndPos = endPos; try { byte[] data = conn.read(startPos, curEndPos); - FileChannel channel = FileChannel.open(filepath,StandardOpenOption.WRITE); - // System.out.println("startPos"+startPos + ", length:"+data.length); - buffer.put(data); - channel.write(buffer); + RandomAccessFile files = new RandomAccessFile(path,"rw"); + files.seek(startPos); + files.write(data); + files.close(); + System.out.println("startPos"+startPos + ", length:"+data.length); } catch (IOException e) { - //e.printStackTrace(); - System.out.println("дļ"); + e.printStackTrace(); } - // } + } conn.close(); + try { + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); + } } } diff --git a/group12/247565311/week3/FileDownloader.java b/group12/247565311/week3/FileDownloader.java index c5ab5fb5d0..1a426c3682 100644 --- a/group12/247565311/week3/FileDownloader.java +++ b/group12/247565311/week3/FileDownloader.java @@ -1,6 +1,5 @@ package week3; - -import java.io.FileNotFoundException; +import java.util.concurrent.CyclicBarrier; import java.io.IOException; import java.io.RandomAccessFile; @@ -11,6 +10,7 @@ import week3.impl.ConnectionManagerImpl; public class FileDownloader { + private int MaxThreadNum = 4; private String url = null,path=null; DownloadListener listener = null; private ConnectionManager cm = new ConnectionManagerImpl(); @@ -20,7 +20,7 @@ public FileDownloader(String weburl,String localpath) { this.path = localpath; } - public void execute(){ + public void execute() throws InterruptedException{ // 在这里实现你的代码, 注意: 需要用多线程实现下载 // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) @@ -35,6 +35,11 @@ public void execute(){ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 Connection conn = null; + CyclicBarrier barr= new CyclicBarrier(MaxThreadNum,new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }); try { conn = cm.open(this.url); int length = conn.getContentLength(); @@ -43,18 +48,13 @@ public void execute(){ tarfile.setLength(length); tarfile.close(); Thread[] threads = new Thread[4]; - threads[0] = new DownloadThread(cm.open(this.url),0,length/4,path); - threads[1] = new DownloadThread(cm.open(this.url),length/4,length/2,path); - threads[2] = new DownloadThread(cm.open(this.url),length/2,3*length/4,path); - threads[3] = new DownloadThread(cm.open(this.url),3*length/4,length,path); + threads[0] = new DownloadThread(barr,cm.open(this.url),0,length/4,path); + threads[1] = new DownloadThread(barr,cm.open(this.url),length/4,length/2,path); + threads[2] = new DownloadThread(barr,cm.open(this.url),length/2,3*length/4,path); + threads[3] = new DownloadThread(barr,cm.open(this.url),3*length/4,length,path); for(int i=0;i<4;i++) threads[i].start(); - threads[0].join(); - threads[1].join(); - threads[2].join(); - threads[3].join(); - this.getListener().notifyFinished(); - } catch (ConnectionException | IOException | InterruptedException e) { + } catch (ConnectionException | IOException e) { e.printStackTrace(); }finally{ if(conn != null){ @@ -71,4 +71,7 @@ public void setConnectionManager(ConnectionManager ucm){ public DownloadListener getListener(){ return this.listener; } + public double getDownPercent(){ + return 0.0; + } } diff --git a/group12/247565311/week3/FileDownloaderTest.java b/group12/247565311/week3/FileDownloaderTest.java index 96893b71e9..3c729218d3 100644 --- a/group12/247565311/week3/FileDownloaderTest.java +++ b/group12/247565311/week3/FileDownloaderTest.java @@ -19,8 +19,8 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "https://edmullen.net/test/rc.jpg"; - String path = "D:\\hellp.jpg"; + String url = "http://music.163.com/api/pc/download/latest"; + String path = "D:\\hellp.exe"; FileDownloader downloader = new FileDownloader(url,path); ConnectionManager cm = new ConnectionManagerImpl(); downloader.setConnectionManager(cm); @@ -30,16 +30,21 @@ public void notifyFinished() { downloadFinished = true; } }); - downloader.execute(); - // 等待多线程下载程序执行完毕 + double time = 0; + try { + downloader.execute(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } while (!downloadFinished) { try { - System.out.println("还没有下载完成,休眠五秒"); - Thread.sleep(5000);//休眠5秒 + Thread.sleep(100);//休眠0.1秒 + + time += 1; } catch (InterruptedException e) { e.printStackTrace(); } } - System.out.println("下载完成!"); + System.out.println("下载完成!耗时:"+time/10.0+" 秒。"); } } diff --git a/group12/247565311/week3/impl/ConnectionImpl.java b/group12/247565311/week3/impl/ConnectionImpl.java index bdd28aa4ec..7173caf56d 100644 --- a/group12/247565311/week3/impl/ConnectionImpl.java +++ b/group12/247565311/week3/impl/ConnectionImpl.java @@ -1,43 +1,65 @@ package week3.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 week3.api.Connection; public class ConnectionImpl implements Connection{ - HttpURLConnection conn = null; + URL url = null; + public ConnectionImpl(String str){ + try { + url = new URL(str); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } // Ҫִأȡֽ // ฺ򿪡ر @Override - public byte[] read(int startPos, int endPos) throws IOException { - if(conn == null || startPos>=endPos) return null; + public byte[] read(int startPos, int endPos) { + HttpURLConnection conn = null; byte[]res = null; - conn.setRequestProperty("Range","bytes="+startPos+"-"+endPos); - int responcode = conn.getResponseCode(); - if(200 < responcode && responcode < 300){ - InputStream input = conn.getInputStream(); - res = new byte[endPos-startPos]; - input.read(res); - input.close(); + try { + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("Range","bytes="+startPos+"-"+endPos); + int responcode = conn.getResponseCode(); + if(200 < responcode && responcode < 300){ + InputStream input = conn.getInputStream(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + res = new byte[2048]; + while(output.size()0)output.write(res,0,len); + else break; + } + return Arrays.copyOf(output.toByteArray(), endPos-startPos); + } + } catch (IOException e) { + e.printStackTrace(); } - conn.disconnect(); + if(conn!=null) conn.disconnect(); return res; } @Override public int getContentLength() { - if(conn == null) return 0; - return conn.getContentLength(); + try{ + URLConnection con = url.openConnection(); + return con.getContentLength(); + }catch(Exception e){ + e.printStackTrace(); + } + return -1; } @Override public void close() { - if(conn == null) return; - conn.disconnect(); - } - public void setConn(HttpURLConnection urlconn) { - conn = urlconn; } } diff --git a/group12/247565311/week3/impl/ConnectionManagerImpl.java b/group12/247565311/week3/impl/ConnectionManagerImpl.java index 68e458b1ca..b4a7cf381f 100644 --- a/group12/247565311/week3/impl/ConnectionManagerImpl.java +++ b/group12/247565311/week3/impl/ConnectionManagerImpl.java @@ -13,16 +13,6 @@ public class ConnectionManagerImpl implements ConnectionManager { ConnectionImpl conImpl = null; @Override public Connection open(String url) throws ConnectionException { - try { - URL urllink = new URL(url); - conImpl = new ConnectionImpl(); - HttpURLConnection httpconn = (HttpURLConnection)urllink.openConnection(); - httpconn.setConnectTimeout(5*1000); - httpconn.setRequestProperty("User-Agent","Mozilla/4.0 (compatiable; MSIE 5.0; Windows NT; DigExt)"); // ģ - conImpl.setConn(httpconn); - } catch (Exception e) { - throw (ConnectionException)e; - } - return conImpl; + return new ConnectionImpl(url); } } diff --git a/group12/247565311/week5/ClassFileLoader.java b/group12/247565311/week5/ClassFileLoader.java new file mode 100644 index 0000000000..fc5e920f19 --- /dev/null +++ b/group12/247565311/week5/ClassFileLoader.java @@ -0,0 +1,63 @@ +package week5; + +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 Exception { + for(String s:clzPaths){ + String filename = s+className+".class"; + File file = new File(filename); + if(file.exists())return loadClassFile(filename); + } + return null; + } + + private byte[] loadClassFile(String clzFileName) throws Exception { + File file = new File(clzFileName); + long filelength = file.length(); + byte[]res = null; + if(filelength>Integer.MAX_VALUE)throw new IOException("ļ"); + try { + FileInputStream fileinput = new FileInputStream(file); + res = new byte[(int) filelength]; + int offset=0,length=0; + while(offset-1)) + offset += length; + fileinput.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return res; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath_V1(){ + String res = ""; + int size = clzPaths.size(); + for(int i=0;i lib = new HashSet(); + class Node{ + int val; + Node next; + public Node(int _val){ + val = _val; + next = null; + } + } + public LRU(int _size){ + if(_size>0) { + this.size = _size; + } + } + public int[] getAll(){ + int length = lib.size(),index = 0; + int []res = new int[length]; + Node p = head.next; + while(p!=null){ + res[index] = p.val; + index += 1; + p = p.next; + } + return res; + } + public void add(int e){ + int index = 0; + if(lib.contains(e)){ + Node p = head; + while(p.next!= null){ + if(p.next.val == e){ + Node newn = p.next; + p.next = newn.next; + newn.next = head.next; + head.next = newn; + break; + } + p = p.next; + } + }else{ + if(lib.size() == size){ + lib.add(e); + Node newn = new Node(e); + newn.next = head.next; + head.next = newn; + Node p = head; + while(p.next.next != null) + p = p.next; + Node deln = p.next; + lib.remove(deln.val); + p.next = null; + }else{ + Node newn = new Node(e); + newn.next = head.next; + head.next = newn; + lib.add(e); + } + } + } +} diff --git a/group12/247565311/week5/LRUTest.java b/group12/247565311/week5/LRUTest.java new file mode 100644 index 0000000000..0ee0d95309 --- /dev/null +++ b/group12/247565311/week5/LRUTest.java @@ -0,0 +1,36 @@ +package week5; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class LRUTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAdd() { + LRU lru = new LRU(5); + lru.add(3); + lru.add(7); + lru.add(5); + lru.add(8); + lru.add(10); + Assert.assertArrayEquals(new int[]{10,8,5,7,3}, lru.getAll()); + lru.add(5); + lru.add(3); + Assert.assertArrayEquals(new int[]{3,5,10,8,7}, lru.getAll()); + lru.add(8); + lru.add(11); + Assert.assertArrayEquals(new int[]{11,8,3,5,10}, lru.getAll()); + } +} diff --git a/group12/349166103/LRUPageFrame.java b/group12/349166103/LRUPageFrame.java new file mode 100644 index 0000000000..4dda68632d --- /dev/null +++ b/group12/349166103/LRUPageFrame.java @@ -0,0 +1,108 @@ + + +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(int Num) { + pageNum=Num; + } + } + + private int capacity; + + + private Node first;// 链表头 + private Node last;// 链表尾 + + private int nodeNum = 0; + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + int isPageNum = isContained(pageNum); + if(isPageNum!=-1){ + int index = 0; + Node node = first; + while(index!=isPageNum){ // move to the Node + node=node.next; + index++; + } + if(index != 0){ + if(node.next == null){ + node.prev.next = null; + }else{ + node.prev.next = node.next; + } + node.next = first; + first = node; + } + }else{ + if(first != null){ + Node tmp = new Node(pageNum); + tmp.next = first; + first.prev = tmp; + first = tmp; + nodeNum++; + if(nodeNum > capacity){ + Node node = first; + for(int i=0;i1.6.1 + + org.apache.commons + commons-lang3 + 3.0 + + + + commons-io + commons-io + 2.4 + diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/ArrayList.java b/group12/377401843/learning/src/main/java/com/zhaogd/array/ArrayList.java similarity index 87% rename from group12/377401843/learning/src/main/java/com/zhaogd/collection/ArrayList.java rename to group12/377401843/learning/src/main/java/com/zhaogd/array/ArrayList.java index d3afc5e01a..d5c5fe04cc 100644 --- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/ArrayList.java +++ b/group12/377401843/learning/src/main/java/com/zhaogd/array/ArrayList.java @@ -1,7 +1,10 @@ -package com.zhaogd.collection; +package com.zhaogd.array; import java.util.Arrays; +import com.zhaogd.collection.Iterator; +import com.zhaogd.collection.List; + public class ArrayList implements List { private int size = 0; @@ -13,7 +16,7 @@ public class ArrayList implements List { * * @Method add * @param o - * @see com.guodong.datastructure.List#add(java.lang.Object) + * @see com.zhaogd.collection.guodong.datastructure.List#add(java.lang.Object) */ public void add(Object o) { ensureCapacityInternal(size + 1); @@ -27,7 +30,7 @@ public void add(Object o) { * @Method add * @param index * @param o - * @see com.guodong.datastructure.List#add(int, java.lang.Object) + * @see com.zhaogd.collection.guodong.datastructure.List#add(int, java.lang.Object) */ public void add(int index, Object o) { checkRangeForAdd(index); @@ -46,7 +49,7 @@ public void add(int index, Object o) { * @Method get * @param index * @return - * @see com.guodong.datastructure.List#get(int) + * @see com.zhaogd.collection.guodong.datastructure.List#get(int) */ public Object get(int index) { checkRangeForGetOrRemove(index); @@ -60,7 +63,7 @@ public Object get(int index) { * @Method remove * @param index * @return - * @see com.guodong.datastructure.List#remove(int) + * @see com.zhaogd.collection.guodong.datastructure.List#remove(int) */ public Object remove(int index) { checkRangeForGetOrRemove(index); @@ -80,7 +83,7 @@ public Object remove(int index) { * * @Method size * @return - * @see com.guodong.datastructure.List#size() + * @see com.zhaogd.collection.guodong.datastructure.List#size() */ public int size() { return size; diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java index d4a0647ab6..b81d015351 100644 --- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java +++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java @@ -1,5 +1,7 @@ package com.zhaogd.collection; +import com.zhaogd.collection.linkedlist.LinkedList; + public class Queue { private LinkedList element = new LinkedList(); diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java new file mode 100644 index 0000000000..39a4e4063d --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java @@ -0,0 +1,164 @@ +package com.zhaogd.collection.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/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java new file mode 100644 index 0000000000..b2fc8c8323 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java @@ -0,0 +1,34 @@ +package com.zhaogd.collection.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()); + + } + +} diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/LinkedList.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LinkedList.java similarity index 94% rename from group12/377401843/learning/src/main/java/com/zhaogd/collection/LinkedList.java rename to group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LinkedList.java index 136f53284e..78721b060a 100644 --- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/LinkedList.java +++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LinkedList.java @@ -1,7 +1,10 @@ -package com.zhaogd.collection; +package com.zhaogd.collection.linkedlist; import java.util.NoSuchElementException; +import com.zhaogd.collection.Iterator; +import com.zhaogd.collection.List; + public class LinkedList implements List { private int size; @@ -15,7 +18,7 @@ public class LinkedList implements List { * * @Method add * @param o - * @see com.guodong.datastructure.List#add(java.lang.Object) + * @see com.zhaogd.collection.guodong.datastructure.List#add(java.lang.Object) */ public void add(Object o) { linkLast(o); @@ -27,7 +30,7 @@ public void add(Object o) { * @Method add * @param index * @param o - * @see com.guodong.datastructure.List#add(int, java.lang.Object) + * @see com.zhaogd.collection.guodong.datastructure.List#add(int, java.lang.Object) */ public void add(int index, Object o) { checkIndexForAdd(index); @@ -54,7 +57,7 @@ public void add(int index, Object o) { * @Method get * @param index * @return - * @see com.guodong.datastructure.List#get(int) + * @see com.zhaogd.collection.guodong.datastructure.List#get(int) */ public Object get(int index) { checkIndexForGet(index); @@ -71,7 +74,7 @@ public Object getLast() { * @Method remove * @param index * @return - * @see com.guodong.datastructure.List#remove(int) + * @see com.zhaogd.collection.guodong.datastructure.List#remove(int) */ public Object remove(int index) { checkIndexForGet(index); diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Stack.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/Stack.java similarity index 80% rename from group12/377401843/learning/src/main/java/com/zhaogd/collection/Stack.java rename to group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/Stack.java index afb01f5f92..85a8800f39 100644 --- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Stack.java +++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/Stack.java @@ -1,4 +1,6 @@ -package com.zhaogd.collection; +package com.zhaogd.collection.stack; + +import com.zhaogd.collection.linkedlist.LinkedList; public class Stack { private LinkedList elementData = new LinkedList(); diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java new file mode 100644 index 0000000000..ecf128b27e --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java @@ -0,0 +1,45 @@ +package com.zhaogd.collection.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..1557b0ead2 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..bf6abbe3fd --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java @@ -0,0 +1,75 @@ +package com.zhaogd.jvm.clz; + +import com.zhaogd.jvm.constant.ClassInfo; +import com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..0bdf47d002 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..9851e063c0 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..0afd79256b --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..4663d4d195 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..bba61aea27 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..61c965bc0a --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..aef7f16d1e --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..1cb411bee2 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.zhaogd.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..c58bcb59d7 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..c8b2e6a4c0 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..7147060b84 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,5 @@ +package com.zhaogd.jvm.loader; + +public class ByteCodeIterator { + +} diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6d04787a99 --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java @@ -0,0 +1,140 @@ +package com.zhaogd.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.zhaogd.jvm.clz.ClassFile; + + + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + 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 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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..e9f656131b --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.zhaogd.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/group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java new file mode 100644 index 0000000000..9c2fcc183e --- /dev/null +++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.zhaogd.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 MAX_CONNECTIONS) { diff --git a/group12/382266293/src/com/coderising/download/FileDownloader.java b/group12/382266293/src/com/coderising/download/FileDownloader.java index cc77b380a9..c756248bb1 100644 --- a/group12/382266293/src/com/coderising/download/FileDownloader.java +++ b/group12/382266293/src/com/coderising/download/FileDownloader.java @@ -44,7 +44,7 @@ public void execute() { try { Connection conn = cm.open(this.url); int length = conn.getContentLength(); - checkLength(length, conn); + System.out.println("file length:" + length); setLocation("C:\\"); @@ -52,7 +52,8 @@ public void execute() { String name = conn.getFileName(); setFileName(name); setTempName(name); - + checkLength(length, conn); + DownloadUtil.createTempFile(tempName, length); int connNumbers = DownloadUtil.calculateConnects(length); @@ -143,14 +144,17 @@ private void setAndStartThreadPool(Connection conn, DownloadThread[] threadPool, threadPool[0] = new DownloadThread(conn, beginPos, endPos); setAndStartThread(threadPool[0], tempName); for (int i = 1; i < connectionNumbers; i++) { - Connection con = cm.open(this.url); beginPos = endPos + 1; endPos = beginPos + batch_size; + Connection con = cm.open(this.url); + if (i == connectionNumbers - 1) { endPos = length - 1; } threadPool[i] = new DownloadThread(con, beginPos, endPos); setAndStartThread(threadPool[i], tempName); + + } } diff --git a/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java b/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java index 05f31103de..61ed430106 100644 --- a/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java +++ b/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java @@ -33,17 +33,27 @@ public byte[] read(int startPos, int endPos) throws IOException { InputStream in = null; ByteArrayOutputStream out = null; try { + httpConn = (HttpURLConnection) url.openConnection(); + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); in = httpConn.getInputStream(); out = new ByteArrayOutputStream(); in = httpConn.getInputStream(); - in.skip(startPos); - byte[] buffer = new byte[endPos-startPos + 1]; + //in.skip(startPos); + int len = 0; byte[] b = new byte[1024]; while((len = in.read(b)) != -1) { out.write(b, 0, len); } + int totalLen = endPos - startPos + 1; + + if (out.size() > totalLen) { + byte[] data = out.toByteArray(); + return data; + } + return out.toByteArray(); + } catch (IOException e) { e.printStackTrace(); } diff --git a/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..81a79a1e04 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,93 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + String clzFileName = "//" + className.replaceAll("\\.", "//") + ".class"; + return loadClassFile(clzFileName); + } + + @SuppressWarnings("resource") + private byte[] loadClassFile(String clzFileName) { + File classFile = getClassFile(clzFileName); + if (null == classFile) { + try { + throw new ClassNotFoundException(clzFileName + " does not exist."); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + RandomAccessFile raf = null; + ByteArrayOutputStream out = null; + try { + out = new ByteArrayOutputStream(); + raf = new RandomAccessFile(classFile, "r"); + int len = 0; + byte[] b = new byte[1024]; + while ((len = raf.read(b)) != -1) { + out.write(b, 0, len); + } + int totalLen = (int) classFile.length(); + + if (out.size() > totalLen) { + byte[] data = out.toByteArray(); + return data; + } + + return out.toByteArray(); + + } catch (IOException e) { + e.printStackTrace(); + } + return null; + + } + + private File getClassFile(String clzFileName) { + + for (String path : clzPaths) { + File file = new File(path + "//" + clzFileName); + if (file.exists()) { + return file; + } + } + return null; + + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath_V1() { + + return null; + } + + public String getClassPath() { + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < clzPaths.size(); i++) { + + sb.append(clzPaths.get(i)); + if (i < clzPaths.size() - 1) { + sb.append(";"); + } + + } + + return sb.toString(); + } + +} diff --git a/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..ab9f6f6d73 --- /dev/null +++ b/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,80 @@ +package com.coderising.jvm.test; + +import java.util.Arrays; + +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\\Administrator\\git\\coding2017n\\group12\\382266293\\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/group12/382266293/src/com/coderising/jvm/test/EmployeeV1.java b/group12/382266293/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..67735a92b0 --- /dev/null +++ b/group12/382266293/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/group12/382266293/src/com/coderising/litestruts/LoginAction.java b/group12/382266293/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..76547ac3b3 --- /dev/null +++ b/group12/382266293/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; + } +} \ No newline at end of file diff --git a/group12/382266293/src/litestruts/Configuration.java b/group12/382266293/src/litestruts/Configuration.java index 9b7d4e8466..4efedbce67 100644 --- a/group12/382266293/src/litestruts/Configuration.java +++ b/group12/382266293/src/litestruts/Configuration.java @@ -1,9 +1,9 @@ package 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; @@ -11,15 +11,13 @@ import static util.Print.*; public class Configuration { - - ActionCfg actionCfg = new ActionCfg(); - + Map actions = new HashMap<>(); + private static Configuration cfg = new Configuration(); private Configuration() { - + } - public static Configuration getNewInstance() { if (cfg == null) { @@ -28,75 +26,108 @@ public static Configuration getNewInstance() { return cfg; } - private String getFile(String fileName) { + public void parse(String fileName) { String src = this.getClass().getPackage().getName(); - return "file://" + src + "\\" + fileName + ".xml"; + String filepath = src.replace(".", "/") + "/" +fileName; + + InputStream is = this.getClass().getResourceAsStream("/" + filepath); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + + } + } - public void parseAction(String src) { - - String fileName = getFile(src); + public void parseXML(InputStream is) { + SAXBuilder reader = new SAXBuilder(); try { - Document doc = reader.build("C:\\struts.xml"); + Document doc = reader.build(is); Element root = doc.getRootElement(); for(Element element : root.getChildren("action")) { - String name = element.getAttributeValue("name"); + String actionName = element.getAttributeValue("name"); String clz = element.getAttributeValue("class"); - actionCfg.actionInfo.put(name, clz); + ActionCfg ac = new ActionCfg(actionName,clz); for(Element e : element.getChildren("result")) { String result = e.getAttributeValue("name"); String jsp = e.getText().trim(); - println("result:" + result + "jsp:" + jsp); - Map res = new HashMap<>(); - res.put(result, jsp); - actionCfg.resultInfo.put(name, res); + ac.addViewResult(result, jsp); } + + actions.put(actionName, ac); } } catch (JDOMException | IOException e) { e.printStackTrace(); } - + } + + + public String getClassName(String action) { + ActionCfg cfg = this.actions.get(action); + if (cfg == null) { + return null; + } + return cfg.getClassName(); + } + + + public String getResultView(String action, String resultName) { + ActionCfg cfg = this.actions.get(action); + if (cfg == null) { + return null; + } + return cfg.getViewResult().get(resultName); } public static void main(String[] args) { Configuration cfg = new Configuration(); - cfg.parseAction("struts"); - Map info = cfg.getActionInfo(); - Map result = cfg.getResultInfo().get("login"); - println(info); - println(result); + cfg.parse("struts.xml"); + String clz = cfg.getClassName("login"); + println(clz); + + } + private static class ActionCfg { - private Map actionInfo; - private Map> resultInfo; - public ActionCfg() { - this.actionInfo = new HashMap(); - this.resultInfo = new HashMap>(); + String name; + String clz; + Map viewResult = new HashMap<>(); + + public Map getViewResult() { + return viewResult; + } + + public ActionCfg(String name, String clz) { + this.name = name; + this.clz = clz; } - - } + public void addViewResult(String result, String jsp) { + viewResult.put(result, jsp); + + } - public Map> getResultInfo() { - - return actionCfg.resultInfo; - } + public String getClassName() { + return clz; + } - public Map getActionInfo() { - - return actionCfg.actionInfo; } - + + + diff --git a/group12/382266293/src/litestruts/ConfigurationTest.java b/group12/382266293/src/litestruts/ConfigurationTest.java index 1b5d2f43e1..e9d41a07c9 100644 --- a/group12/382266293/src/litestruts/ConfigurationTest.java +++ b/group12/382266293/src/litestruts/ConfigurationTest.java @@ -1,32 +1,54 @@ package litestruts; -import java.util.HashMap; -import java.util.Map; - import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; + + public class ConfigurationTest { + + Configuration cfg = Configuration.getNewInstance(); + + + @Before public void setUp() throws Exception { + + cfg.parse("struts.xml"); } @After public void tearDown() throws Exception { + } @Test - public void testGetGetterMethods() { - Configuration cfg = Configuration.getNewInstance(); - Map actionName = new HashMap<>(); - actionName.put("login","com.coderising.action.LoginAction"); - actionName.put("logout","com.coderising.action.LogoutAction"); + 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); - //Assert.assertTrue(cfg.getActionName().containsKey(actionName)); + 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/group12/382266293/src/litestruts/StrutsTest.java b/group12/382266293/src/litestruts/StrutsTest.java index 35686c8e30..4b59f846f5 100644 --- a/group12/382266293/src/litestruts/StrutsTest.java +++ b/group12/382266293/src/litestruts/StrutsTest.java @@ -1,17 +1,19 @@ package litestruts; -import java.beans.IntrospectionException; -import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import org.junit.Assert; import org.junit.Test; + + + + public class StrutsTest { @Test - public void testLoginActionSuccess() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + public void testLoginActionSuccess() { String actionName = "login"; @@ -27,7 +29,7 @@ public void testLoginActionSuccess() throws InstantiationException, IllegalAcces } @Test - public void testLoginActionFailed() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException { + public void testLoginActionFailed() { String actionName = "login"; Map params = new HashMap(); params.put("name","test"); @@ -38,4 +40,4 @@ public void testLoginActionFailed() throws InstantiationException, IllegalAccess 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/group12/382266293/src/litestruts/struts.xml b/group12/382266293/src/litestruts/struts.xml index fb0c2be3de..4c6eeabbd4 100644 --- a/group12/382266293/src/litestruts/struts.xml +++ b/group12/382266293/src/litestruts/struts.xml @@ -1,10 +1,10 @@ - + /jsp/homepage.jsp /jsp/showLogin.jsp - + /jsp/welcome.jsp /jsp/error.jsp diff --git a/group12/446031103/src/com/coderising/download/DownloadThread.java b/group12/446031103/src/com/coderising/download/DownloadThread.java index 900a3ad358..4daa1baf3c 100644 --- a/group12/446031103/src/com/coderising/download/DownloadThread.java +++ b/group12/446031103/src/com/coderising/download/DownloadThread.java @@ -1,5 +1,10 @@ package com.coderising.download; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + import com.coderising.download.api.Connection; public class DownloadThread extends Thread{ @@ -7,14 +12,34 @@ public class DownloadThread extends Thread{ Connection conn; int startPos; int endPos; - - public DownloadThread( 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 { + 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/group12/446031103/src/com/coderising/download/FileDownloader.java b/group12/446031103/src/com/coderising/download/FileDownloader.java index c3c8a3f27d..5cbb88410a 100644 --- a/group12/446031103/src/com/coderising/download/FileDownloader.java +++ b/group12/446031103/src/com/coderising/download/FileDownloader.java @@ -1,7 +1,11 @@ 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.ConnectionException; import com.coderising.download.api.ConnectionManager; import com.coderising.download.api.DownloadListener; @@ -14,9 +18,12 @@ public class FileDownloader { ConnectionManager cm; + private String localFile; + private static final int DOWNLOAD_TRHEAD_NUM = 3; - public FileDownloader(String _url) { + public FileDownloader(String _url,String _localFile) { this.url = _url; + this.localFile = _localFile; } @@ -34,16 +41,36 @@ public void execute(){ // 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[][] ranges = allocateDownloadRange(DOWNLOAD_TRHEAD_NUM, length); - new DownloadThread(conn,0,length-1).start(); + for(int i=0; i< DOWNLOAD_TRHEAD_NUM; i++){ - } catch (ConnectionException e) { + + 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){ @@ -56,6 +83,37 @@ public void execute(){ } + 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 openConnection; + try { + openConnection = url.openConnection(); + return openConnection.getContentLength(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } return 0; } diff --git a/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java index 172371dd55..18836b4a28 100644 --- a/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java +++ b/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -9,7 +9,7 @@ public class ConnectionManagerImpl implements ConnectionManager { @Override public Connection open(String url) throws ConnectionException { - return null; + return new ConnectionImpl(url); } } diff --git a/group12/446031103/src/com/coderising/download/test/ConnectionTest.java b/group12/446031103/src/com/coderising/download/test/ConnectionTest.java new file mode 100644 index 0000000000..cda74451ca --- /dev/null +++ b/group12/446031103/src/com/coderising/download/test/ConnectionTest.java @@ -0,0 +1,53 @@ +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 + 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/group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java b/group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java new file mode 100644 index 0000000000..a3e7d24429 --- /dev/null +++ b/group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java @@ -0,0 +1,59 @@ +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() { + + String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + + FileDownloader downloader = new FileDownloader(url,"E:\\TEST\\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/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..e021b94d38 --- /dev/null +++ b/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,43 @@ +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; + + + } + + private byte[] loadClassFile(String clzFileName) { + + return null; + } + + + + public void addClassPath(String path) { + + } + + public String getClassPath_V1(){ + + return null; + } + + public String getClassPath(){ + return null; + } + + + + + +} diff --git a/group12/446031103/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/446031103/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..50eb1be6fa --- /dev/null +++ b/group12/446031103/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;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); + } + + + + private void parseXML(InputStream is) { + SAXReader reader = new SAXReader(); + try { + Document document = reader.read(is); + Element struts = document.getRootElement(); + Iterator actions = struts.elementIterator(); + while (actions.hasNext()) { + Element action = (Element) actions.next(); + String actionName=action.attributeValue("name"); + String actionClass=action.attributeValue("class"); + ActionConfig ac = new ActionConfig(actionName,actionClass); + Iterator results = action.elementIterator(); + while (results.hasNext()) { + Element result = (Element) results.next(); + String name = result.attributeValue("name"); + String viewName = result.getStringValue(); + ac.addViewResult(name, viewName); + } + this.actions.put(actionName, ac); + } + } catch (DocumentException e) { + + e.printStackTrace(); + } + + } + + + + public String getClassName(String actionName) { + ActionConfig actionConfig = actions.get(actionName); + if(null==actionConfig) + return null; + return actionConfig.getClassName(); + } + + public String getResultView(String actionName, String resultName) { + ActionConfig actionConfig =actions.get(actionName); + if(null==actionConfig) + return null; + return actionConfig.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/group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java b/group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..f4af430eef --- /dev/null +++ b/group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,39 @@ +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/group12/446031103/src/com/coderising/litestruts/LoginAction.java b/group12/446031103/src/com/coderising/litestruts/LoginAction.java index 39af2d5c26..dcdbe226ed 100644 --- a/group12/446031103/src/com/coderising/litestruts/LoginAction.java +++ b/group12/446031103/src/com/coderising/litestruts/LoginAction.java @@ -36,7 +36,4 @@ public void setPassword(String password){ public String getMessage(){ return this.message; } - public void setMessage(String message){ - this.message = message; - } } diff --git a/group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java b/group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..c9bbd312ef --- /dev/null +++ b/group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,75 @@ +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 List getGetterMethods(Class clz) { + return getMethods(clz,"get"); + } + + public static List getMethods(Class clz,String startsWithName) { + List methods = new ArrayList<>(); + for (Method method : clz.getDeclaredMethods()) { + if(method.getName().startsWith(startsWithName)){ + methods.add(method); + } + } + return methods; + } + + public static void setParams(Object o, Map params) { + List methods = getSetterMethods(o.getClass()); + for (String name : params.keySet()) { + String methodName = "set"+name; + for (Method method : methods) { + if(methodName.equalsIgnoreCase(method.getName())){ + try { + method.invoke(o, params.get(name)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + }; + } + + } + } + + public static Map getParams(Object o) { + Map params = new HashMap<>(); + List methods = getGetterMethods(o.getClass()); + for (Method method : methods) { + try { + String name=method.getName(); + name = name.replaceFirst("get", "").toLowerCase(); + Object value = method.invoke(o); + params.put(name, value); + } 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(); + } + } + return params; + } + +} diff --git a/group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java b/group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..f1b233be37 --- /dev/null +++ b/group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,96 @@ +package com.coderising.litestruts; + +import static org.junit.Assert.*; + +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 ClassNotFoundException { + 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 testGetGetterMethod() throws ClassNotFoundException { + 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("getName"); + expectedNames.add("getPassword"); + expectedNames.add("getMessage"); + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + @Test + public void testSetterParams() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException { + 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.setParams(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 testGetterParams() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + LoginAction la = (LoginAction) clz.newInstance(); + la.setName("test"); + la.setPassword("123456"); + Map params =ReflectionUtil.getParams(la); + 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/group12/446031103/src/com/coderising/litestruts/Struts.java b/group12/446031103/src/com/coderising/litestruts/Struts.java index 8f5913d836..c4466c1d02 100644 --- a/group12/446031103/src/com/coderising/litestruts/Struts.java +++ b/group12/446031103/src/com/coderising/litestruts/Struts.java @@ -9,6 +9,7 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import org.dom4j.Document; @@ -24,92 +25,42 @@ * @version: V1.0 */ public class Struts { + private final static Configuration cfg = new Configuration("struts.xml"); public static View runAction(String actionName, Map parameters) { - Map xmlDoc = getXMLDOC(actionName); - Map viewMap = new HashMap(); - View view = new View(); - view.setParameters(viewMap); - try { - Class classz = Class.forName(xmlDoc.get(actionName)); - LoginAction la = (LoginAction) classz.newInstance(); - la.setName(parameters.get("name")); - la.setPassword(parameters.get("password")); - Method exectue = classz.getMethod("execute", null); - Object result = exectue.invoke(la, null); - Field[] fields = classz.getDeclaredFields(); - for (Field field : fields) { - PropertyDescriptor pd = new PropertyDescriptor(field.getName(), classz); - Method readMethod = pd.getReadMethod(); - viewMap.put(field.getName(), (String) readMethod.invoke(la, null)); - } - view.setJsp(xmlDoc.get(result)); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchMethodException 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 (IntrospectionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + /* - * 0. 读取配置文件struts.xml 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象), + * 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, + * 那就应该调用 setName和setPassword方法 + * 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + * 3.通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + * 放到View对象的parameters + * 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, * 放到View对象的jsp字段中。 */ - return view; - } - /** - * @MethodName: getXMLDOC - * @Description: 解析xml文件 - * @param actionName - * @return - * @return: Map - */ - private static Map getXMLDOC(String actionName) { - Map xmldoc = new HashMap(); - // 解析struts.xml文件 - // 创建SAXReader的对象reader - SAXReader reader = new SAXReader(); + String className = cfg.getClassName(actionName); + try { - // 通过reader对象的read方法读取struts.xml,得到document对象 - Document document = reader.read(new File("src/com/coderising/litestruts/struts.xml")); - // 获取根节点 - Element struts = document.getRootElement(); - // 迭代节点 - Iterator actions = struts.elementIterator(); - while (actions.hasNext()) { - Element action = (Element) actions.next(); - if (actionName.equals(action.attributeValue("name"))) { - xmldoc.put(action.attributeValue("name"), action.attributeValue("class")); - Iterator results = action.elementIterator(); - while (results.hasNext()) { - Element result = (Element) results.next(); - xmldoc.put(result.attributeValue("name"), result.getStringValue()); - } - break; - } - } - } catch (DocumentException e) { + Class clz = Class.forName(className); + Object o = clz.newInstance(); + ReflectionUtil.setParams(o, parameters); + Method exectue = clz.getDeclaredMethod("execute"); + String resultName=(String) exectue.invoke(o); + Map params = ReflectionUtil.getParams(o); + String resultView = cfg.getResultView(actionName, resultName); + View v = new View(); + v.setJsp(resultView); + v.setParameters(params); + return v; + } catch (Exception e) { + // TODO Auto-generated catch block e.printStackTrace(); - } - return xmldoc; + } + + + return null; } + } diff --git a/group12/446031103/src/com/coding/basic/ArrayList.java b/group12/446031103/src/com/datastructure/array/ArrayList.java similarity index 87% rename from group12/446031103/src/com/coding/basic/ArrayList.java rename to group12/446031103/src/com/datastructure/array/ArrayList.java index bc3d75c3f6..9731daec06 100644 --- a/group12/446031103/src/com/coding/basic/ArrayList.java +++ b/group12/446031103/src/com/datastructure/array/ArrayList.java @@ -1,7 +1,10 @@ -package com.coding.basic; +package com.datastructure.array; import java.util.Arrays; +import com.datastructure.basic.Iterator; +import com.datastructure.basic.List; + /** @@ -21,7 +24,7 @@ public class ArrayList implements List { * * @Method add 添加 * @param o 元素 - * @see com.coding.basic.List#add(java.lang.Object) + * @see com.datastructure.basic.List#add(java.lang.Object) */ public void add(Object o){ ensureCapacity(size + 1); @@ -35,7 +38,7 @@ public void add(Object o){ * @Method add 添加 * @param index 下标 * @param o 元素 - * @see com.coding.basic.List#add(int, java.lang.Object) + * @see com.datastructure.basic.List#add(int, java.lang.Object) */ public void add(int index, Object o){ validate(index); @@ -51,7 +54,7 @@ public void add(int index, Object o){ * @Method get 取得 * @param index 下标 * @return - * @see com.coding.basic.List#get(int) + * @see com.datastructure.basic.List#get(int) */ public Object get(int index){ validate(index); @@ -64,7 +67,7 @@ public Object get(int index){ * @Method remove 删除 * @param index 下标 * @return 删除的元素 - * @see com.coding.basic.List#remove(int) + * @see com.datastructure.basic.List#remove(int) */ public Object remove(int index){ validate(index); @@ -80,7 +83,7 @@ public Object remove(int index){ * * @Method size 集合大小 * @return 集合大小 - * @see com.coding.basic.List#size() + * @see com.datastructure.basic.List#size() */ public int size(){ return this.size; diff --git a/group12/446031103/src/com/coderising/array/ArrayUtil.java b/group12/446031103/src/com/datastructure/array/ArrayUtil.java similarity index 51% rename from group12/446031103/src/com/coderising/array/ArrayUtil.java rename to group12/446031103/src/com/datastructure/array/ArrayUtil.java index a771999a22..a5b62040bc 100644 --- a/group12/446031103/src/com/coderising/array/ArrayUtil.java +++ b/group12/446031103/src/com/datastructure/array/ArrayUtil.java @@ -1,9 +1,11 @@ -package com.coderising.array; +package com.datastructure.array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array; + public class ArrayUtil { /** @@ -14,13 +16,15 @@ public class ArrayUtil { * @return */ public void reverseArray(int[] origin){ - int end = origin.length-1; - int temp ; - for (int i = 0; i < end; i++,end--) { - temp=origin[i]; - origin[i]=origin[end]; - origin[end] = temp; + if(null ==origin ||0==origin.length){ + return; + } + for (int i = 0,j=origin.length-1; i < j; i++,j--) { + int temp=origin[i] ; + origin[i]= origin[j]; + origin[i]=temp; } + } /** @@ -32,23 +36,18 @@ public void reverseArray(int[] origin){ */ public int[] removeZero(int[] oldArray){ - int zeroCnt = 0; - for (int i : oldArray) { - if(0==i){ - zeroCnt++; - } - - } - int size = 0; - int [] result = new int[oldArray.length-zeroCnt]; - for (int i : oldArray) { - if(0!=i){ - result[size]=i; - size++; + if(null==oldArray||oldArray.length ==0){ + return null; + } + int notZeroCnt = 0; + int [] temp = new int[oldArray.length]; + for (int i = 0; i < oldArray.length; i++) { + if(oldArray[i]!=0){ + temp[notZeroCnt++] = oldArray[i]; } - } - return result; + System.arraycopy(temp, 0, temp, 0, notZeroCnt); + return temp; } /** @@ -60,31 +59,34 @@ public int[] removeZero(int[] oldArray){ */ public int[] merge(int[] array1, int[] array2){ - //合拼数组,缺排序,缺去重 + if(null==array1&&null==array2){ + return null; + } int [] temp = new int[array1.length+array2.length]; - System.arraycopy(array1, 0, temp, 0, array1.length); - System.arraycopy(array2, 0, temp, array1.length, array2.length); - List resultList= new ArrayList(); - for (int i : temp) { - if(!resultList.contains(i)) - resultList.add(i); - }//已去重数组,缺排序 - int [] result = new int[resultList.size()]; - for (int i = 0; i < resultList.size(); i++) { - result[i] = resultList.get(i); - } - //冒泡排序 - for (int i = 0; i < result.length-1; i++) { - for (int j = 0; j < result.length-i-1; j++) { - if(result[j]>result[j+1]){ - int tempInt = result[j]; - result[j] =result[j+1]; - result[j+1] = tempInt; - } + int i = 0; + int j = 0; + int count = 0; + while (iarray2[j]){ + temp[count++] = array2[j++]; + } + if(array1[i]==array2[j]){ + temp[count++] = array2[j]; + i++; + j++; } - - } - return result; + } + while(i==array1.length&&j resultList= new ArrayList(); - if(max!=second) - add(first,second,max,resultList); - int [] result = new int[resultList.size()]; - for (int i = 0; i < resultList.size(); i++) { - result[i] = resultList.get(i); - } - return result; + if(1==max){ + return new int[0]; + } + if(2==max){ + return new int[]{1,1}; + } + int [] temp = new int [max] ; + temp[0] = 1; + temp[1] = 1; + int cnt = 2; + for (int i = 2 ; i < max; i++) { + temp[i] = temp[i-1] + temp[i-2]; + if(temp[i]>=max){ + break; + }else{ + cnt++; + } + } + return Arrays.copyOf(temp, cnt); } /** @@ -126,23 +137,30 @@ public int[] fibonacci(int max){ * @return */ public int[] getPrimes(int max){ - List resultList= new ArrayList(); + if(max<2){ + return new int[0]; + } + int [] temp = new int[max]; + int cnt = 0; for (int i = 2; i < max; i++) { - boolean isAdd = true; - for (int j = 2; j < i; j++) { - if(0==i%j){ - isAdd = false; - break; - } + if(isPrime(i)){ + temp[cnt++] = i; } - if(isAdd) - resultList.add(i); } - int [] result = new int[resultList.size()]; - for (int i = 0; i < resultList.size(); i++) { - result[i] = resultList.get(i); + return Arrays.copyOf(temp, cnt); + } + + private boolean isPrime(int n){ + int i = 2; + while(i resultList= new ArrayList(); - for (int i = 1; i < max; i++) { - int temp = 0; + if(max<0){ + return null; + } + int cnt = 0; + int [] temp = new int[max]; + for (int i = 2; i < max; i++) { + int sum = 0; for (int j = 1; j < i; j++) { - if(0==i%j){ - temp+=j; + if(i%j==0){ + sum+=j; } } - if(i==temp) - resultList.add(i); - } - int [] result = new int[resultList.size()]; - for (int i = 0; i < resultList.size(); i++) { - result[i] = resultList.get(i); + if(sum==i){ + temp[cnt++] = i; + } } - return result; + return Arrays.copyOf(temp, cnt); } /** @@ -179,24 +198,19 @@ public int[] getPerfectNumbers(int max){ * @return */ public String join(int[] array, String seperator){ - return Arrays.toString(array).replace("[", "").replace("]", "").replace(", ", seperator); + if(null==array||array.length==0){ + return ""; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + sb.append(array[i]); + if(i add(int number1,int number2,int max,List resultList){ - if(number2size) + this.last.prev.next = null; + this.last = getLastNode(size); + }else{ + this.last.prev.next = null; + } + + + } + + private boolean isOut(){ + return this.addCnt<=this.capacity; + } + + private Node getLastNode(int sizes) { + Node node=this.first; + for (int i = 0; i < sizes; i++) { + node = node.next; + } + return node; + } + + private boolean contain(Object o){ + Node node = this.first; + + while(null!=node.next){ + + node = node.next; + + if(Objects.equals(node.pageNum,o)){ + return true; + } + + } + return false; + } + + private Node getNode(Object o){ + Node node = this.first; + + while(null!=node.next){ + + node = node.next; + + if(Objects.equals(node.pageNum,o)){ + return node; + } + + } + return null; + } + + + + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node.next != null){ + node = node.next; + buffer.append(node.pageNum); + if(node.next != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} \ No newline at end of file diff --git a/group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java b/group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..956aa6c697 --- /dev/null +++ b/group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java @@ -0,0 +1,46 @@ +package com.datastructure.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(7); +// Assert.assertEquals("7", frame.toString()); +// frame.access(7); +// Assert.assertEquals("7", frame.toString()); +// frame.access(2); +// Assert.assertEquals("2,7", frame.toString()); +// frame.access(7); +// Assert.assertEquals("7,2", frame.toString()); +// frame.access(3); +// Assert.assertEquals("3,7,2", frame.toString()); +// frame.access(2); +// Assert.assertEquals("2,3,7", frame.toString()); +// frame.access(2); +// Assert.assertEquals("2,3,7", frame.toString()); + } + +} diff --git a/group12/446031103/src/com/coding/basic/LinkedList.java b/group12/446031103/src/com/datastructure/linklist/LinkedList.java similarity index 74% rename from group12/446031103/src/com/coding/basic/LinkedList.java rename to group12/446031103/src/com/datastructure/linklist/LinkedList.java index 33f6d79e65..1236734423 100644 --- a/group12/446031103/src/com/coding/basic/LinkedList.java +++ b/group12/446031103/src/com/datastructure/linklist/LinkedList.java @@ -1,11 +1,8 @@ -package com.coding.basic; +package com.datastructure.linklist; +import java.util.Stack; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.junit.experimental.theories.Theories; - -import sun.reflect.Reflection; +import com.datastructure.basic.Iterator; +import com.datastructure.basic.List; /** * @@ -26,7 +23,7 @@ public class LinkedList implements List { * * @Method add 添加 * @param o 元素 - * @see com.coding.basic.List#add(java.lang.Object) + * @see com.datastructure.basic.List#add(java.lang.Object) */ public void add(Object o){ Node newNode = new Node(o, null); @@ -48,7 +45,7 @@ public void add(Object o){ * @Method add 增加 * @param index 下标 * @param o 元素 - * @see com.coding.basic.List#add(int, java.lang.Object) + * @see com.datastructure.basic.List#add(int, java.lang.Object) */ public void add(int index , Object o){ validate(index); @@ -85,7 +82,7 @@ public void add(int index , Object o){ * @Method get 取得 * @param index 下标 * @return - * @see com.coding.basic.List#get(int) + * @see com.datastructure.basic.List#get(int) */ public Object get(int index){ validate(index); @@ -102,7 +99,7 @@ public Object get(int index){ * @Method remove 删除 * @param index 下标 * @return - * @see com.coding.basic.List#remove(int) + * @see com.datastructure.basic.List#remove(int) */ public Object remove(int index){ Node removeNode = (Node) get(index); @@ -128,7 +125,7 @@ public Object remove(int index){ * * @Method size 集合大小 * @return 集合大小 - * @see com.coding.basic.List#size() + * @see com.datastructure.basic.List#size() */ public int size(){ return size; @@ -233,13 +230,21 @@ public Node(Object data, Node next) { * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ - public void reverse(){ - for (int i = size; i <0; i--) { - Node last=(Node) get(i); - if(0==i) - last.next = null; - else - last.next = (Node) get(i-1); + public void reverse(){ + Stack s=new Stack(); + Node currentNode = head; + while(null!=currentNode){ + s.push(currentNode); + Node tempNode=currentNode.next; + currentNode.next = null; + currentNode = tempNode; + } + head = (Node) s.pop(); + currentNode= head; + while(!s.isEmpty()){ + Node tempNode=(Node) s.pop(); + currentNode.next = tempNode; + currentNode = tempNode; } } @@ -250,7 +255,7 @@ public void reverse(){ */ public void removeFirstHalf(){ - for (int i = 0; i < size%2; i++) { + for (int i = 0; i < size/2; i++) { remove(i); } } @@ -261,10 +266,15 @@ public void removeFirstHalf(){ * @param length */ public void remove(int i, int length){ - for (int a = i; a < i+length; a++) { - remove(a); + if(i<0||i>=size){ + throw new IndexOutOfBoundsException(); + } + int len = size-1>=length?length:size-1; + int k = 0; + while(k callClass=Reflection.getCallerClass(); + public int[] getElements(LinkedList list){ + int [] arr = new int [list.size()]; for (int i = 0; i < list.size; i++) { - Node node=(Node) list.get(i); - try { - Method method=callClass.getDeclaredMethod("get", new Class[]{int.class}); - result[i]=(int) method.invoke(callClass, new Object[]{node.data}); - } catch (NoSuchMethodException | SecurityException 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(); - } + arr[i] = (int) get((int)list.get(i)); } - return null; + return arr; } /** @@ -321,15 +314,29 @@ public void subtract(LinkedList list){ /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + * @throws Exception */ - public void removeDuplicateValues(){ - for (int i = 0; i < size; i++) { - Node node=(Node) get(i); - for (int j = i+1; j < size; j++) { - Node newNode=(Node) get(j); - if(newNode.data.equals(node.data)) - remove(j); + public void removeDuplicateValues() throws Exception{ + if(null==head){ + throw new Exception(); + } + Node pre = head; + Node cur =head; + while(null!=cur.next){ + cur = cur.next; + Object o=pre.data; + while(cur.data == o){ + if(null==cur.next){ + pre.next = null; + } + pre.next = cur.next; + size--; + cur = cur.next; + if(null==cur){ + break; + } } + pre = pre.next; } } @@ -340,11 +347,24 @@ public void removeDuplicateValues(){ * @param max */ public void removeRange(int min, int max){ - for (int i = 0; i < size; i++) { - Node node=(Node) get(i); - if((int)node.data>min && (int)node.data=max){ + end = i; + break; + } + i++; } + remove(star,end-star); } /** @@ -352,17 +372,24 @@ public void removeRange(int min, int max){ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ - public LinkedList intersection( LinkedList list){ + public LinkedList intersection( LinkedList list){ + if(list==null){ + return null; + } LinkedList newList = new LinkedList(); - for (int i = 0; i < size; i++) { - Node node=(Node) get(i); - for (int j = 0; j < list.size; j++) { - Node newNode=(Node) get(j); - if(newNode.data.equals(node.data)){ - newList.add(node); - break; - } - + int i1=0; + int i2=0; + if(i1value2){ + i2++; } } return newList; diff --git a/group12/563253496/week3_file_download/src/com/coderising/array/ArrayUtil.java b/group12/563253496/week3_file_download/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..e5ddb476a6 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java b/group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..a3dc676a90 --- /dev/null +++ b/group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,50 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; +import com.sun.org.apache.xpath.internal.SourceTree; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +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; + } + + 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 (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + + } +} diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..8b35a9a11d --- /dev/null +++ b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,126 @@ +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.CyclicBarrier; + + +public class FileDownloader { + + String url; + 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() { + @Override + public void run() { + listener.notifyFinished(); + } + }); + + + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + this.createPlaceHolderFile(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(); + } + + //new DownloadThread(conn, 0, length - 1, localFile, barrier).start(); + + } catch (ConnectionException e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + private void createPlaceHolderFile(String fileName, int contentLen) { + try { + RandomAccessFile file = new RandomAccessFile(fileName, "rw"); + for (int i = 0; i < contentLen; i++) { + file.write(0); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + 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; + } + + + 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/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloaderTest.java b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..7ec4c1f2e3 --- /dev/null +++ b/group12/563253496/week3_file_download/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"; + String url ="http://desk.fd.zol-img.com.cn/t_s1920x1080c5/g3/M04/0B/06/Cg-4V1Q_K_2IS20UAAvKmTmHyYIAAQLGwOZI-YAC8qx308.jpg"; + FileDownloader downloader = new FileDownloader(url,"d:/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/group12/563253496/week3_file_download/src/com/coderising/download/api/Connection.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionManager.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/download/api/DownloadListener.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..37b413558d --- /dev/null +++ b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,73 @@ +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; + +public class ConnectionImpl implements Connection { + + static final int BUFFER_SIZE = 1024; + URL url; + + ConnectionImpl(String _url) { + try { + url = new URL(_url); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + + @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[] buffer = new byte[BUFFER_SIZE]; + int totalLen = endPos - startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + while (baos.size() < totalLen) { + int len = is.read(buffer); + if (len < 0) { + break; + } + baos.write(buffer); + } + if (baos.size() > totalLen) { + byte[] temp = baos.toByteArray(); + return Arrays.copyOf(temp, totalLen); + } + return baos.toByteArray(); + + + } + + @Override + public int getContentLength() { + try { + URLConnection conn = url.openConnection(); + return conn.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + + + } + + @Override + public void close() { + + + } + +} diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..f4a83cdbf6 --- /dev/null +++ b/group12/563253496/week3_file_download/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); + //return null; + } + +} diff --git a/group12/563253496/week3_file_download/src/com/coderising/litestruts/LoginAction.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/litestruts/Struts.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..85e2e22de3 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/litestruts/StrutsTest.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coderising/litestruts/View.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coding/basic/ArrayList.java b/group12/563253496/week3_file_download/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..1f185736f9 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coding/basic/BinaryTreeNode.java b/group12/563253496/week3_file_download/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group15/1502_1617273078/src/com/coding/basic/Iterator.java b/group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java similarity index 100% rename from group15/1502_1617273078/src/com/coding/basic/Iterator.java rename to group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java diff --git a/group09/41689722.eulerlcs/2.code/jmr-61-170312-multiThreadDownload/src/main/java/com/github/eulerlcs/jmr/multiDL/algorithm/LinkedList.java b/group12/563253496/week3_file_download/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 group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/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/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/List.java b/group12/563253496/week3_file_download/src/com/coding/basic/List.java similarity index 100% rename from group15/1513_121469918/HomeWork20170305/src/com/coding/basic/List.java rename to group12/563253496/week3_file_download/src/com/coding/basic/List.java diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/Queue.java b/group12/563253496/week3_file_download/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..36e516e266 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coding/basic/Stack.java b/group12/563253496/week3_file_download/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..a5a04de76d --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..5f56b80bff --- /dev/null +++ b/group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,81 @@ +package com.coderising.jvm.loader; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + String path = getClassFilePath(className); + if (path != null) { + try { + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path)); + int count = bis.available(); + byte[] content = new byte[count]; + int len = bis.read(content,0,count); + return content; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + + + } + + 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 sb = new StringBuilder(); + for (String s : clzPaths) { + sb.append(s); + sb.append(";"); + } + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + + private String getClassFilePath(String className) { + StringBuilder sb = new StringBuilder(); + for (String path : clzPaths + ) { + sb.append(path); + sb.append("\\"); + char[] classname = className.toCharArray(); + for (int i = 0; i < classname.length; i++) { + if (classname[i] == '.') { + sb.append("\\"); + + } else { + sb.append(classname[i]); + } + } + sb.append(".class"); + String classpath = sb.toString(); + File file = new File(classpath); + if (file.exists()) { + return classpath; + } + } + return null; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/ClassFileloaderTest.java b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java similarity index 66% rename from group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/ClassFileloaderTest.java rename to group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java index b544e7ddc4..4127673b7e 100644 --- a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/ClassFileloaderTest.java +++ b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -1,91 +1,80 @@ -package me.lzb.loader; +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 { +public class ClassFileloaderTest { - static String path1 = EmployeeV1.class.getResource("/").getPath(); + + static String path1 = "D:\\mygit\\coding2017\\group12\\563253496\\week4_jvm1\\out\\production\\week4_jvm1"; static String path2 = "C:\\temp"; - - - + + + @Before - public void setUp() throws Exception { + public void setUp() throws Exception { } @After public void tearDown() throws Exception { } - - - + @Test - public void testPath(){ - - String s = EmployeeV1.class.getResource("/").getPath(); - String s2 = EmployeeV1.class.getResource("").getPath(); - System.out.println(s); - System.out.println(s2); - - } - - - - @Test - public void testClassPath(){ - + 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 Exception{ - + public void testClassFileLength() { + ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); - - String className = "me.lzb.loader.EmployeeV1"; - + + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); - + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1036, byteCodes.length); - + Assert.assertEquals(1056, byteCodes.length); + } - - - @Test - public void testMagicNumber() throws Exception{ + + + @Test + public void testMagicNumber(){ ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); - String className = "me.lzb.loader.EmployeeV1"; + 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 +* @since
 29, 2017
+* @version 1.0 +*/ 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/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/group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java b/group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..8f8607162f --- /dev/null +++ b/group13/2729382520/L4/src/io/github/vxzh/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,82 @@ +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/group13/2931408816/lesson4/src/main/java/com/coding/basic/BinaryTreeNode.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group13/2931408816/lesson4/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/group15/1521_653895972/src/com/coding/basic/Iterator.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/Iterator.java similarity index 100% rename from group15/1521_653895972/src/com/coding/basic/Iterator.java rename to group13/2931408816/lesson4/src/main/java/com/coding/basic/Iterator.java diff --git a/group15/1521_653895972/src/com/coding/basic/List.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/List.java similarity index 100% rename from group15/1521_653895972/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/group13/2931408816/lesson4/src/main/java/com/coding/basic/Stack.java b/group13/2931408816/lesson4/src/main/java/com/coding/basic/Stack.java new file mode 100644 index 0000000000..459ec560b4 --- /dev/null +++ b/group13/2931408816/lesson4/src/main/java/com/coding/basic/Stack.java @@ -0,0 +1,24 @@ +package com.coding.basic; + +import com.coding.basic.array.ArrayList; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + } + + public Object pop(){ + return null; + } + + public Object peek(){ + return null; + } + public boolean isEmpty(){ + return false; + } + public int size(){ + return -1; + } +} diff --git a/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/group24/798277403/src/week3/impl/ConnectionManagerImpl.java b/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionManagerImpl.java similarity index 56% rename from group24/798277403/src/week3/impl/ConnectionManagerImpl.java rename to group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionManagerImpl.java index 130d7e5aaa..e5bd712bfb 100644 --- a/group24/798277403/src/week3/impl/ConnectionManagerImpl.java +++ b/group13/413007522/lesson03/src/main/java/cn/xl/c3/impl/ConnectionManagerImpl.java @@ -1,14 +1,19 @@ -package week3.impl; +package cn.xl.c3.impl; -import week3.api.Connection; -import week3.api.ConnectionException; -import week3.api.ConnectionManager; -public class ConnectionManagerImpl implements ConnectionManager { +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/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/group04/120549547/base/src/com/coding/basic/List.java b/group14/187114392/homework/src/com/coding/basic/List.java similarity index 99% rename from group04/120549547/base/src/com/coding/basic/List.java rename to group14/187114392/homework/src/com/coding/basic/List.java index d47df585d9..10d13b5832 100644 --- a/group04/120549547/base/src/com/coding/basic/List.java +++ b/group14/187114392/homework/src/com/coding/basic/List.java @@ -1,7 +1,6 @@ package com.coding.basic; public interface List { - public void add(Object o); public void add(int index, Object o); public Object get(int index); 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/.classpath b/group14/187114392/work_1_20170225/.classpath deleted file mode 100644 index fceb4801b5..0000000000 --- a/group14/187114392/work_1_20170225/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/group14/187114392/work_1_20170225/.gitignore b/group14/187114392/work_1_20170225/.gitignore deleted file mode 100644 index ae3c172604..0000000000 --- a/group14/187114392/work_1_20170225/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin/ 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/.project b/group14/187114392/work_1_20170225/.project deleted file mode 100644 index fab8d7f04c..0000000000 --- a/group14/187114392/work_1_20170225/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - 2017Learning - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - 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/187114392/work_1_20170225/2017Learning.iml b/group14/187114392/work_1_20170225/2017Learning.iml deleted file mode 100644 index c4678227ee..0000000000 --- a/group14/187114392/work_1_20170225/2017Learning.iml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file 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" + endPos); + } + public void run(){ + try { + File file = new File("test.jpg"); + RandomAccessFile out = null; + if (file != null) { + out = new RandomAccessFile(file,"rwd"); + } + + byte[] buffer = new byte[1024]; + /* out.seek(startPos); + out.write(conn.read(startPos,endPos));*/ + InputStream in = conn.getHttpURLConnection().getInputStream(); + in.skip(startPos); + int len = 0; + while ((len = in.read(buffer)) != 1) { + if (len < 0) { + break; + }else { + //System.out.println("len length"+len); + out.write(buffer, 0, len); + } + } + + out.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group15/1502_1617273078/data-structure/src/com/coderising/download/FileDownloader.java b/group15/1502_1617273078/data-structure/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c0750bfe65 --- /dev/null +++ b/group15/1502_1617273078/data-structure/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,97 @@ +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.IOException; +import java.io.RandomAccessFile; + + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + public static synchronized void writefile(int index, RandomAccessFile randomAccessFile, byte[] bytes) throws IOException { + randomAccessFile.seek(index); + randomAccessFile.write(bytes); + } + + public void execute(int threadnum) 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 filelength = conn.getContentLength(); + //randomAccessFile.setLength(filelength); + int[] index = new int[threadnum+1]; + for (int i = 0; i totalLen) { + byte[] datas = baos.toByteArray(); + return Arrays.copyOf(datas, totalLen); + } + + + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + int length = httpURLConnection.getContentLength(); + return length; + } + + @Override + public void close() { + httpURLConnection.disconnect(); + + } + + public void setHttpURLConnection(HttpURLConnection httpURLConnection) { + this.httpURLConnection = httpURLConnection; + } + + public HttpURLConnection getHttpURLConnection() { + return httpURLConnection; + } +} diff --git a/group15/1502_1617273078/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group15/1502_1617273078/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..d894491a1c --- /dev/null +++ b/group15/1502_1617273078/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,30 @@ +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.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException, IOException { + URL url1 = new URL(url); + HttpURLConnection conn = (HttpURLConnection) url1.openConnection(); + conn.setRequestMethod("GET"); + //conn.setRequestProperty(); + conn.setConnectTimeout(10*1000); + //防止屏蔽程序抓取而返回403错误 + conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + ConnectionImpl connection = new ConnectionImpl(); + connection.setHttpURLConnection(conn); + //conn.connect(); + //conn.getContentLength(); + return connection; + } + +} diff --git a/group15/1502_1617273078/data-structure/src/com/coderising/litestruts/LoginAction.java b/group15/1502_1617273078/data-structure/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group15/1502_1617273078/data-structure/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/group15/1502_1617273078/src/com/coderising/litestruts/Struts.java b/group15/1502_1617273078/data-structure/src/com/coderising/litestruts/Struts.java similarity index 100% rename from group15/1502_1617273078/src/com/coderising/litestruts/Struts.java rename to group15/1502_1617273078/data-structure/src/com/coderising/litestruts/Struts.java diff --git a/group15/1502_1617273078/src/com/coderising/litestruts/StrutsTest.java b/group15/1502_1617273078/data-structure/src/com/coderising/litestruts/StrutsTest.java similarity index 100% rename from group15/1502_1617273078/src/com/coderising/litestruts/StrutsTest.java rename to group15/1502_1617273078/data-structure/src/com/coderising/litestruts/StrutsTest.java diff --git a/group15/1502_1617273078/data-structure/src/com/coderising/litestruts/View.java b/group15/1502_1617273078/data-structure/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group15/1502_1617273078/data-structure/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/group15/1502_1617273078/src/com/coding/basic/ArrayList.java b/group15/1502_1617273078/data-structure/src/com/coding/basic/ArrayList.java similarity index 100% rename from group15/1502_1617273078/src/com/coding/basic/ArrayList.java rename to group15/1502_1617273078/data-structure/src/com/coding/basic/ArrayList.java diff --git a/group15/1502_1617273078/data-structure/src/com/coding/basic/Iterator.java b/group15/1502_1617273078/data-structure/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..06ef6311b2 --- /dev/null +++ b/group15/1502_1617273078/data-structure/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/group15/1502_1617273078/data-structure/src/com/coding/basic/LinkedList.java b/group15/1502_1617273078/data-structure/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..84e3e5fc23 --- /dev/null +++ b/group15/1502_1617273078/data-structure/src/com/coding/basic/LinkedList.java @@ -0,0 +1,382 @@ +package com.coding.basic; + + + +public class LinkedList implements List { + + private Node head; + private int thesize; + + + public void add(Object o){ + if (head == null) { + head = new Node(o,null); + /* head.data = o; + head.next = null;*/ + thesize++; + } else { + addLast(o); + } + } + public void add(int index , Object o){ + if (index > thesize) { + throw new IndexOutOfBoundsException(); + } else if (index == thesize) { + addLast(o); + } else if(index= thesize) { + throw new IndexOutOfBoundsException(); + } else if(index==0){ + return head.data; + } else + { + Node x = head; + for (int j = 1; j 7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + int cusize = thesize; + //创建list副本,内容一致 + LinkedList listbak=new LinkedList(); + for (int i = 0; i 5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + Node node=head; + int sign=thesize; + for (int i = 1; i <=sign/2 ; i++) { + node = node.next; + thesize--; + + } + head = node; + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始(删除的元素包括了i) + * @param i + * @param length + */ + public void remove(int i, int length){ + Node node = head; + if (i == 0) { + for (int j = 1; j <=length ; j++) { + node = node.next; + thesize--; + } + head = node; + } else if (i != 0 && length < thesize-i) { + int sizesign = thesize; + Node f; + Node l; + for (int j =1; j 101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] res = new int[list.size()]; + for (int i = 0; i max){ + + } else if (min < (Integer) (get(size() - 1))&&(Integer) (get(size() - 1))(Integer) (get(0))){ + Node node = head; + if ((Integer) head.data > min) { + Node newhead = new Node(null,null); + head = newhead; + thesize = 0; + }else + for (int i = 1; i min) { + node.next = null; + thesize = i + 1; + }else { + node = node.next; + } + } + } else if (min < (Integer) (get(0))&&(Integer) (get(0)) max) { + head = node; + thesize = thesize - i; + break; + } + } + }else { + Node node = head; + Node nodemin=null; + Node nodemax = null; + int minsign = 0; + int maxsign=0; + for (int i = 1; i min) { + nodemin = node; + minsign = i-1; + break; + } + node = node.next; + } + for (int i = 1; i max) { + nodemax = node.next; + maxsign = i+1; + break; + } + node = node.next; + } + nodemin.next = nodemax; + System.out.println(minsign); + System.out.println(maxsign); + thesize = thesize - (maxsign - minsign); + } + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList list1 = new LinkedList(); + for (int i = 0; i thesize) { + throw new IndexOutOfBoundsException(); + } else if (index == thesize) { + addLast(o); + } else if(index= thesize) { + throw new IndexOutOfBoundsException(); + } else if(index==0){ + return head.data; + } else + { + Node x = head; + for (int j = 1; j 7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + int cusize = thesize; + //创建list副本,内容一致 + LinkedList listbak=new LinkedList(); + for (int i = 0; i 5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + Node node=head; + int sign=thesize; + for (int i = 1; i <=sign/2 ; i++) { + node = node.next; + thesize--; + + } + head = node; + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始(删除的元素包括了i) + * @param i + * @param length + */ + public void remove(int i, int length){ + Node node = head; + if (i == 0) { + for (int j = 1; j <=length ; j++) { + node = node.next; + thesize--; + } + head = node; + } else if (i != 0 && length < thesize-i) { + int sizesign = thesize; + Node f; + Node l; + for (int j =1; j 101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] res = new int[list.size()]; + for (int i = 0; i max){ + + } else if (min < (Integer) (get(size() - 1))&&(Integer) (get(size() - 1))(Integer) (get(0))){ + Node node = head; + if ((Integer) head.data > min) { + Node newhead = new Node(null,null); + head = newhead; + thesize = 0; + }else + for (int i = 1; i min) { + node.next = null; + thesize = i + 1; + }else { + node = node.next; + } + } + } else if (min < (Integer) (get(0))&&(Integer) (get(0)) max) { + head = node; + thesize = thesize - i; + break; + } + } + }else { + Node node = head; + Node nodemin=null; + Node nodemax = null; + int minsign = 0; + int maxsign=0; + for (int i = 1; i min) { + nodemin = node; + minsign = i-1; + break; + } + node = node.next; + } + for (int i = 1; i max) { + nodemax = node.next; + maxsign = i+1; + break; + } + node = node.next; + } + nodemin.next = nodemax; + System.out.println(minsign); + System.out.println(maxsign); + thesize = thesize - (maxsign - minsign); + } + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList list1 = new LinkedList(); + for (int i = 0; i +* @since
03/12/2017
+* @version 1.0 +*/ +public class LinkedListTest extends TestCase { +public LinkedListTest(String name) { +super(name); +} + +public void setUp() throws Exception { +super.setUp(); +} + +public void tearDown() throws Exception { +super.tearDown(); +} + +/** +* +* Method: add(Object o) +* +*/ +public void testAddO() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: add(int index, Object o) +* +*/ +public void testAddForIndexO() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: get(int index) +* +*/ +public void testGet() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: remove(int index) +* +*/ +public void testRemoveIndex() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: size() +* +*/ +public void testSize() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: addFirst(Object o) +* +*/ +public void testAddFirst() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: addLast(Object o) +* +*/ +public void testAddLast() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: removeFirst() +* +*/ +public void testRemoveFirst() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: removeLast() +* +*/ +public void testRemoveLast() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: iterator() +* +*/ +public void testIterator() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: reverse() +* +*/ +public void testReverse() throws Exception { +//TODO: Test goes here... + LinkedList list = new LinkedList(); + list.add(3); + list.add(8); + list.add(10); + list.reverse(); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + System.out.print(iterator.next()+" "); + } +} + +/** +* +* Method: removeFirstHalf() +* +*/ +public void testRemoveFirstHalf() throws Exception { +//TODO: Test goes here... + LinkedList list = new LinkedList(); + list.add(2); + + list.add(3); + list.add(8); + list.add(10); + list.add(11); + + list.removeFirstHalf(); + // linklist.addFirst(2); + //System.out.println(linklist.size()); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + // String s= new String(iterator.next()); + System.out.print(iterator.next()+" "); + } +} + +/** +* +* Method: remove(int i, int length) +* +*/ +public void testRemoveForILength() throws Exception { +//TODO: Test goes here... + LinkedList list = new LinkedList(); + list.add(2); + + list.add(3); + list.add(8); + list.add(10); + list.add(11); + + list.remove(3,6); + // linklist.addFirst(2); + System.out.println(list.size()); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + // String s= new String(iterator.next()); + System.out.print(iterator.next()+" "); + } + +} + +/** +* +* Method: getElements(LinkedList linklist) +* +*/ +public void testGetElements() throws Exception { +//TODO: Test goes here... + LinkedList list = new LinkedList(); + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + //linklist.remove(3,6); + LinkedList listb = new LinkedList(); + listb.add(1); + listb.add(3); + listb.add(4); + listb.add(6); + int[] res; + res=list.getElements(listb); + //System.out.println(linklist.size()); + for (int i = 0; i +* @since
 12, 2017
+* @version 1.0 +*/ +public class LinkedListbakTest { + +@Before +public void before() throws Exception { +} + +@After +public void after() throws Exception { +} + +/** +* +* Method: add(Object o) +* +*/ +@Test +public void testAddO() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: add(int index, Object o) +* +*/ +@Test +public void testAddForIndexO() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: get(int index) +* +*/ +@Test +public void testGet() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: remove(int index) +* +*/ +@Test +public void testRemove() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: size() +* +*/ +@Test +public void testSize() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: addFirst(Object o) +* +*/ +@Test +public void testAddFirst() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: addLast(Object o) +* +*/ +@Test +public void testAddLast() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: removeFirst() +* +*/ +@Test +public void testRemoveFirst() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: removeLast() +* +*/ +@Test +public void testRemoveLast() throws Exception { +//TODO: Test goes here... +} + +/** +* +* Method: iterator() +* +*/ +@Test +public void testIterator() throws Exception { +//TODO: Test goes here... + LinkedListbak list = new LinkedListbak(); + list.add("3"); + list.add("8"); + list.add("10"); + //linklist.reverse(); + System.out.println(list.size()); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + // String s= new String(iterator.next()); + System.out.print(iterator.next()); + } +} + + +} diff --git a/group15/1502_1617273078/data-structure/test.jpg b/group15/1502_1617273078/data-structure/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..95f6fe5b31c53a4e24a50c4a3adc8518ba57420d GIT binary patch literal 45215 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�%57{pal;v)_DD^cAtAM?STj~he3I`S& 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 literal 0 HcmV?d00001 diff --git a/group15/1502_1617273078/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group15/1502_1617273078/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..2e7d56be17 --- /dev/null +++ b/group15/1502_1617273078/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,86 @@ +package com.coderising.jvm.loader; + +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) { + File file = new File(className); + + List list = new ArrayList(); + FileInputStream s = null; + try { + s = new FileInputStream(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + byte[] buffer = new byte[1024]; + int len = 0; + try { + while ((len = s.read(buffer)) != 1) { + if (len < 0) { + break; + }else { + for (int i = 0; i - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group15/1503_1311822904/downland&LinkedList/LinkedList.java b/group15/1503_1311822904/downland&LinkedList/LinkedList.java new file mode 100644 index 0000000000..7354329ae8 --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/LinkedList.java @@ -0,0 +1,385 @@ +package com.coding.basic; + +public class LinkedList implements List { + + private int size = 0; + private Node head=new Node(null); + + public LinkedList(int[] ints) { + int length=ints.length; + if(length>0){ + for(int i=0;i7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(this.head.next==null) + return; + int[] ints=new int[size]; + Node n=head; + for(int i=size-1;i>-1;i--) { + ints[i] = (int) n.data; + n=n.next; + } + LinkedList temp=new LinkedList(ints); + head=temp.head; + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 [4 2 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 [5 2 + + */ + public void removeFirstHalf(){ + int middle=size/2; + head=getNode(middle); + size=size-middle; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length) throws Exception { + size=size-length; + if(i+length>size) { + throw new Exception("不够长"); + } + Node start; + if(i==0){ + start=head; + }else { + start=getNode(i-1); + } + + Node n=start; + while (length>-1){ + n=n.next; + length--; + } + start.next=n; + + } + /** + * 假定当前链表和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) throws CloneNotSupportedException { + int length=list.size(); + if (length<1) + return null; + int[] result=new int[length]; + LinkedList newList= this; + + Node indexNode= list.head;//第一个坐标节点 + int index=(Integer) indexNode.data; + Node newFirstNode=newList.getNode(index);//第一个目标节点 + result[0]= (int) newFirstNode.data;//数放到结果数组 + if(length==1) + return result; + + int i=1; + while (i= min) {//第一个进去范围的 + startNode = prevNode; + break; + } + prevNode=n; + n = n.next; + } + int count=0; + while (n!=null) { + data=(int)n.data; + if (data >= max) {//第一个出范围的 + endNode = n; + break; + } + count++;//没出范围就继续计数 + n = n.next;//下一个 + } + startNode.next=endNode; + size=size-count; + if ((int)head.data>=min){ + size--; + head=head.next; + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList list3=new LinkedList(); + Node aNode=this.head; + Node bNode=list.head; + while (aNode!=null&&bNode!=null){ + if((int)aNode.data>(int)bNode.data){ + bNode=bNode.next; + }else if((int)bNode.data>(int)aNode.data){ + aNode=aNode.next; + }else { + list3.add((int)bNode.data); + bNode=bNode.next; + aNode=aNode.next; + } + } + + + return list3; + } +} diff --git a/group15/1503_1311822904/downland&LinkedList/LinkedListTest.java b/group15/1503_1311822904/downland&LinkedList/LinkedListTest.java new file mode 100644 index 0000000000..057351008a --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/LinkedListTest.java @@ -0,0 +1,265 @@ +package test.com.coding.basic; + + +import com.coding.basic.Iterator; +import com.coding.basic.LinkedList; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class LinkedListTest { + int[] a={0,101,202,303,404,505,606}; +LinkedList linkedList ; +@Before +public void before() throws Exception { + linkedList =new LinkedList(a); +} + +@After +public void after() throws Exception { + +} + +/** +* +* Method: add(Object o) +* +*/ +@Test +public void testAddO() throws Exception { + linkedList.add(5); + int[] b={0,101,202,303,404,505,606,5}; + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: add(int index, Object o) +* +*/ +@Test +public void testAddForIndexO() throws Exception { + linkedList.add(2,5); + int[] b={0,101,5,202,303,404,505,606}; + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: get(int index) +* +*/ +@Test +public void testGet() throws Exception { + Assert.assertEquals(505,linkedList.get(5)); +} + +/** +* +* Method: remove(int index) +* +*/ +@Test +public void testRemoveIndex() throws Exception { + int[] b={0,101,202,303,404,606}; + Assert.assertEquals(505,linkedList.remove(5)); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: size() +* +*/ +@Test +public void testSize() throws Exception { + Assert.assertEquals(7,linkedList.size()); +} + +/** +* +* Method: addFirst(Object o) +* +*/ +@Test +public void testAddFirst() throws Exception { + int[] b={-99,0,101,202,303,404,505,606}; + linkedList.addFirst(-99); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: addLast(Object o) +* +*/ +@Test +public void testAddLast() throws Exception { + int[] b={0,101,202,303,404,505,606,-99}; + linkedList.addLast(-99); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* + +*/ +@Test +public void testRemoveFirst() throws Exception { + int[] b={101,202,303,404,505,606,}; + linkedList.removeFirst(); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: removeLast() +* +*/ +@Test +public void testRemoveLast() throws Exception { + int[] b={0,101,202,303,404,505}; + linkedList.removeLast(); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: iterator() +* +*/ +@Test +public void testIterator() throws Exception { + LinkedList temp=new LinkedList(); + Iterator iterator=linkedList.iterator(); + while (iterator.hasNext()){ + temp.add(iterator.next()); + } + Assert.assertEquals(temp.toString(),linkedList.toString()); +} + +/** +* +* Method: reverse() +* +*/ +@Test +public void testReverse() throws Exception { + int[] b={9,7,3}; + int[] a={3,7,9}; + linkedList=new LinkedList(a); + linkedList.reverse(); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 [4 2 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 [5 2 + + + */ +@Test +public void testRemoveFirstHalf() throws Exception { + + + int[] b={303,404,505,606}; + + linkedList.removeFirstHalf(); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: remove(int i, int length) +* +*/ +@Test +public void testRemoveForILength() throws Exception { + int[] b={0,101,404,505,606}; + linkedList.remove(2,2); + Assert.assertEquals((new LinkedList(b)).toString(),linkedList.toString()); +} + +/** +* +* Method: getElements(LinkedList list) + * 11->101->202->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] +* +*/ +@Test +public void testGetElements() throws Exception { + int[] b={1,3,4,6}; + int[] c = linkedList.getElements(new LinkedList(b)); + int[] d={101,303,404,606}; + Assert.assertEquals(new LinkedList(d).toString(),new LinkedList(c).toString()); +} + +/** +* +* Method: subtract(LinkedList list) +* +*/ +@Test +public void testSubtract() throws Exception { + int[] b={1,303,606}; + LinkedList list2=new LinkedList(b); + linkedList.subtract(list2); + + int[] result={0,101,202,404,505}; + Assert.assertEquals(new LinkedList(result).toString(),linkedList.toString()); +} + +/** +* +* Method: removeDuplicateValues() +* +*/ +@Test +public void testRemoveDuplicateValues() throws Exception { + int[] a={1,1,1,1,2,2,2,3,3,4,5,6,7,7,7,8,9,11,11,11}; + int[] b={1,2,3,4,5,6,7,8,9,11}; + LinkedList ah= new LinkedList(a); + ah.removeDuplicateValues(); + Assert.assertEquals(new LinkedList(b).toString(),ah.toString()); +} + +/** +* +* Method: removeRange(int min, int max) +* +*/ +@Test +public void testRemoveRange() throws Exception { + int[] a={0,101,202,303,404,505,606}; + int[] b={0,101, 404,505,606}; + LinkedList bl=new LinkedList(b); + linkedList.removeRange(200,400); + Assert.assertEquals(bl.toString(),linkedList.toString()); +} + +/** +* +* Method: intersection(LinkedList list) +* +*/ +@Test +public void testIntersection() throws Exception { + int[] a={0,101,202,303,404 }; + int[] b={0,101, 404,505,606}; + int[] c={0,101, 404}; + LinkedList bl=new LinkedList(b); + LinkedList al=new LinkedList(a); + LinkedList cl=new LinkedList(c); + + Assert.assertEquals(cl.toString(),al.intersection(bl).toString()); +} + + +} diff --git a/group15/1503_1311822904/downland&LinkedList/src/DownloadThread.java b/group15/1503_1311822904/downland&LinkedList/src/DownloadThread.java new file mode 100644 index 0000000000..18b2dc23cf --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/DownloadThread.java @@ -0,0 +1,41 @@ +import api.Connection; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.CountDownLatch; + +public class DownloadThread extends Thread{ + private CountDownLatch threadsSignal; + private Connection conn; + private int startPos; + private int endPos; + static Map partMap = (Map) Collections.synchronizedMap(new TreeMap( + new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o1.compareTo(o2); + } + })); + + + + public DownloadThread(Connection conn, int startPos, int endPos, CountDownLatch threadSignal){ + this.threadsSignal = threadSignal; + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ //TODO 具体下载的线程 + + try { + partMap.put(startPos,conn.read(startPos,endPos)); + } catch (IOException e) { + e.printStackTrace(); + }finally { + if(conn != null){ + conn.close(); + } + threadsSignal.countDown();//线程结束时计数器减1 + } + } +} diff --git a/group15/1503_1311822904/downland&LinkedList/src/FileDownloader.java b/group15/1503_1311822904/downland&LinkedList/src/FileDownloader.java new file mode 100644 index 0000000000..3137a5ce4d --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/FileDownloader.java @@ -0,0 +1,91 @@ +import api.Connection; +import api.ConnectionManager; +import api.DownloadListener; + +import java.io.FileOutputStream; +import java.util.concurrent.CountDownLatch; + + +public class FileDownloader { + + String url; + + DownloadListener downloadListener; + + ConnectionManager connectionManager; + + + public FileDownloader(String _url) { + this.url = _url; + + } + int threadNum=3; + public void execute(){//TODO 主体 + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (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 connection = null; + try { + connection = connectionManager.open(this.url); + int totalLength = connection.getContentLength(); + + //计算出每一块的大小 + int perLength =totalLength /threadNum +1; + + CountDownLatch threadSignal = new CountDownLatch(threadNum);//初始化countDown + for (int i = 0; i < threadNum; i++) {//开threadNum个线程 + int length = perLength; + //如果是最后一块, 则使用总数来减去前面块的总和 + if (i == (threadNum - 1)) { + length = totalLength- i * perLength; + } + connection = connectionManager.open(this.url); + new DownloadThread(connection,i * perLength,i* perLength+length-1,threadSignal).start(); + + } + FileOutputStream fos = new FileOutputStream("D:\\new.jpg"); + + threadSignal.await();//等待所有子线程执行完 + for(Integer i:DownloadThread.partMap.keySet()){ + fos.write(DownloadThread.partMap.get(i)); + } + fos.close(); + getDownloadListener().notifyFinished(); + } catch (Exception e) { + e.printStackTrace(); + + } + + + + + } + + public void setDownloadListener(DownloadListener downloadListener) { + this.downloadListener = downloadListener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.connectionManager = ucm; + } + + public DownloadListener getDownloadListener(){ + return this.downloadListener; + } + +} diff --git a/group15/1503_1311822904/downland&LinkedList/src/FileDownloaderTest.java b/group15/1503_1311822904/downland&LinkedList/src/FileDownloaderTest.java new file mode 100644 index 0000000000..94dd275394 --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/FileDownloaderTest.java @@ -0,0 +1,53 @@ +import api.DownloadListener; +import impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://h.hiphotos.baidu.com/baike/s%3D220/sign=d37711ea2b2eb938e86d7df0e56385fe/32fa828ba61ea8d37a8f660f930a304e251f580f.jpg"; + + FileDownloader fileDownloader = new FileDownloader(url); + + fileDownloader.setConnectionManager(new ConnectionManagerImpl()); + + fileDownloader.setDownloadListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + fileDownloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group15/1503_1311822904/downland&LinkedList/src/api/Connection.java b/group15/1503_1311822904/downland&LinkedList/src/api/Connection.java new file mode 100644 index 0000000000..dd940f0351 --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/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/group15/1503_1311822904/downland&LinkedList/src/api/ConnectionException.java b/group15/1503_1311822904/downland&LinkedList/src/api/ConnectionException.java new file mode 100644 index 0000000000..60a2043e44 --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/api/ConnectionException.java @@ -0,0 +1,5 @@ +package api; + +public class ConnectionException extends Exception { + +} diff --git a/group24/798277403/src/week3/api/ConnectionManager.java b/group15/1503_1311822904/downland&LinkedList/src/api/ConnectionManager.java similarity index 90% rename from group24/798277403/src/week3/api/ConnectionManager.java rename to group15/1503_1311822904/downland&LinkedList/src/api/ConnectionManager.java index 4af7a12be1..29fdb371e1 100644 --- a/group24/798277403/src/week3/api/ConnectionManager.java +++ b/group15/1503_1311822904/downland&LinkedList/src/api/ConnectionManager.java @@ -1,4 +1,4 @@ -package week3.api; +package api; public interface ConnectionManager { /** diff --git a/group24/798277403/src/week3/api/DownloadListener.java b/group15/1503_1311822904/downland&LinkedList/src/api/DownloadListener.java similarity index 78% rename from group24/798277403/src/week3/api/DownloadListener.java rename to group15/1503_1311822904/downland&LinkedList/src/api/DownloadListener.java index da4eb7abc3..b8ab21d462 100644 --- a/group24/798277403/src/week3/api/DownloadListener.java +++ b/group15/1503_1311822904/downland&LinkedList/src/api/DownloadListener.java @@ -1,4 +1,4 @@ -package week3.api; +package api; public interface DownloadListener { public void notifyFinished(); diff --git a/group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionImpl.java b/group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionImpl.java new file mode 100644 index 0000000000..66a1d12f62 --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionImpl.java @@ -0,0 +1,44 @@ +package impl; + +import api.Connection; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +public class ConnectionImpl implements Connection { + private HttpURLConnection urlConnection; + private InputStream inputStream; + public ConnectionImpl(HttpURLConnection urlConnection) { + this.urlConnection=urlConnection; + + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException {//TODO 实际下载 + urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + urlConnection.connect(); + InputStream inputStream = urlConnection.getInputStream(); + byte[] buffer = new byte[endPos-startPos+1]; + inputStream.read(buffer); + return buffer; + } + + @Override + public int getContentLength() { + try { + urlConnection.connect(); + } catch (IOException e) { + e.printStackTrace(); + } + return urlConnection.getContentLength(); + + } + + @Override + public void close() { + + + } + +} diff --git a/group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionManagerImpl.java b/group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..f3649be2be --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/impl/ConnectionManagerImpl.java @@ -0,0 +1,27 @@ +package impl; + +import api.Connection; +import api.ConnectionException; +import api.ConnectionManager; + +import java.net.HttpURLConnection; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + private URL url; + @Override + public Connection open(String urlStr) throws ConnectionException { + Connection connection; + try { + url= new URL(urlStr); + HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); + connection=new ConnectionImpl(urlConnection); + } catch (Exception e) { + e.printStackTrace(); + throw new ConnectionException(); + } + + return connection; + } + +} diff --git a/group15/1503_1311822904/downland&LinkedList/src/impl/URLConnectionDownloader.java b/group15/1503_1311822904/downland&LinkedList/src/impl/URLConnectionDownloader.java new file mode 100644 index 0000000000..74c75bd4a1 --- /dev/null +++ b/group15/1503_1311822904/downland&LinkedList/src/impl/URLConnectionDownloader.java @@ -0,0 +1,47 @@ +package impl; + +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; + +/** + * 使用URLConnection下载文件或图片并保存到本地。 + * + * @author 老紫竹(laozizhu.com) + */ +public class URLConnectionDownloader { + public static void main(String[] args) throws Exception { + download("http://www.laozizhu.com/images/logo.gif", "laozizhu.com.gif"); + } + + /** + * 下载文件到本地 + * + * @param urlString 被下载的文件地址 + * @param filename 本地文件名 + * @throws Exception 各种异常 + */ + public static void download(String urlString, String filename) throws Exception { + // 构造URL + URL url = new URL(urlString); + // 打开连接 + URLConnection con = url.openConnection(); + // 输入流 + InputStream is = con.getInputStream(); + // 1K的数据缓冲 + byte[] bs = new byte[1024]; + // 读取到的数据长度 + int len; + // 输出的文件流 + OutputStream os = new FileOutputStream(filename); + // 开始读取 + while ((len = is.read(bs)) != -1) { + os.write(bs, 0, len); + } + // 完毕,关闭所有链接 + os.close(); + is.close(); + } +} diff --git a/group15/1503_1311822904/myCollection/src/LinkedList.java b/group15/1503_1311822904/myCollection/src/LinkedList.java index 69fad47ace..d0ac0f732c 100644 --- a/group15/1503_1311822904/myCollection/src/LinkedList.java +++ b/group15/1503_1311822904/myCollection/src/LinkedList.java @@ -149,34 +149,111 @@ public String toString(){ return s; } - public static void main(String[] arg){ - LinkedList a=new LinkedList(); - // a.removeFirst(); - a.addFirst("first"); - a.addLast("ll"); - a.add(0); - a.add(1); - a.add("2"); - a.add("3"); - a.add("4"); - a.add("5"); - a.add("six"); - a.add("七"); - a.add(8); - System.out.println(a); - Iterator iterator=a.iterator(); - while (iterator.hasNext()) - System.out.println(iterator.next()); - /*System.out.println(a.size); - System.out.println(a); - System.out.println(a.remove(3)); - System.out.println(a.remove(3)); - a.removeFirst(); - a.removeLast(); - System.out.println(a);*/ + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + PLinkedList p= (PLinkedList) this.clone(); + this.clear(); + for(int i=p.size()-1;i>-1;i--){ + this.add(p.get(i)); + } + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 [4 2 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 [5 2 + + */ + public void removeFirstHalf(){ + PLinkedList p= (PLinkedList) this.clone(); + this.clear(); + for(int i=p.size()/2;isize) { + throw new Exception("不够长"); + } + for(int j=1;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 p= (PLinkedList) this.clone(); + for(T t:this){ + p.remove(t); + if(p.contains(t)){ + this.remove(t); + } + } - //System.out.println(a.get(3)); - //System.out.println(a.get(99)); + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + int middle=this.size(); + int i=middle; + int j=middle+1; + + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + return null; } } diff --git a/group15/1507_977996067/src/task3/download/DownloadThread.java b/group15/1507_977996067/src/task3/download/DownloadThread.java new file mode 100644 index 0000000000..291cb6f289 --- /dev/null +++ b/group15/1507_977996067/src/task3/download/DownloadThread.java @@ -0,0 +1,48 @@ +package task3.download; + +import task3.download.api.Connection; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread { + + Connection conn; + int startPos; + int endPos; + File file; + + 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, File file) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.file = file; + } + + public void run() { + RandomAccessFile randomAccessFile = null; + try { + byte[] read = conn.read(startPos, endPos); + randomAccessFile = new RandomAccessFile(file, "rw"); + randomAccessFile.skipBytes(startPos); + randomAccessFile.write(read, 0, endPos - startPos + 1); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (randomAccessFile != null) + try { + randomAccessFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/group15/1507_977996067/src/task3/download/FileDownloader.java b/group15/1507_977996067/src/task3/download/FileDownloader.java new file mode 100644 index 0000000000..55c8b43dca --- /dev/null +++ b/group15/1507_977996067/src/task3/download/FileDownloader.java @@ -0,0 +1,80 @@ +package task3.download; + +import task3.download.api.Connection; +import task3.download.api.ConnectionException; +import task3.download.api.ConnectionManager; +import task3.download.api.DownloadListener; + +import java.io.File; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() { + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + + File targetFile = new File("f:/" + url.substring(url.lastIndexOf("/"))); + try { + if (cm == null) + throw new RuntimeException("connection manager not ready"); + conn = cm.open(this.url); + if (conn == null) + throw new RuntimeException("connect time out"); + int length = conn.getContentLength(); + //多线程个数 + int count = length / 102400 + 1; + for (int i = 0; i < count; i++) { + int startPos = i * 102400; + int endPos = (i == (count - 1)) ? (length - 1) : (startPos + 102399); + System.out.println(endPos); + Thread th = new DownloadThread(conn, startPos, endPos, targetFile); + th.start(); + th.join(); + } + listener.notifyFinished(); + } catch (InterruptedException | 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/group15/1507_977996067/src/task3/download/FileDownloaderTest.java b/group15/1507_977996067/src/task3/download/FileDownloaderTest.java new file mode 100644 index 0000000000..536c225f63 --- /dev/null +++ b/group15/1507_977996067/src/task3/download/FileDownloaderTest.java @@ -0,0 +1,55 @@ +package task3.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import task3.download.api.ConnectionManager; +import task3.download.api.DownloadListener; +import task3.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/group15/1507_977996067/src/task3/download/api/Connection.java b/group15/1507_977996067/src/task3/download/api/Connection.java new file mode 100644 index 0000000000..e9ce626831 --- /dev/null +++ b/group15/1507_977996067/src/task3/download/api/Connection.java @@ -0,0 +1,23 @@ +package task3.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/group15/1507_977996067/src/task3/download/api/ConnectionException.java b/group15/1507_977996067/src/task3/download/api/ConnectionException.java new file mode 100644 index 0000000000..a9c2c5ef83 --- /dev/null +++ b/group15/1507_977996067/src/task3/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package task3.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group15/1507_977996067/src/task3/download/api/ConnectionManager.java b/group15/1507_977996067/src/task3/download/api/ConnectionManager.java new file mode 100644 index 0000000000..2275f4d12a --- /dev/null +++ b/group15/1507_977996067/src/task3/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package task3.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group15/1507_977996067/src/task3/download/api/DownloadListener.java b/group15/1507_977996067/src/task3/download/api/DownloadListener.java new file mode 100644 index 0000000000..6d0cb69e7c --- /dev/null +++ b/group15/1507_977996067/src/task3/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package task3.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group15/1507_977996067/src/task3/download/impl/ConnectionImpl.java b/group15/1507_977996067/src/task3/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..d2388394a7 --- /dev/null +++ b/group15/1507_977996067/src/task3/download/impl/ConnectionImpl.java @@ -0,0 +1,44 @@ +package task3.download.impl; + +import task3.download.api.Connection; + +import java.io.IOException; +import java.io.InputStream; + +public class ConnectionImpl implements Connection { + + private InputStream inputStream; + + public ConnectionImpl(InputStream inputStream) { + this.inputStream = inputStream; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + byte[] buffer = new byte[endPos - startPos + 1]; + inputStream.read(buffer, 0, buffer.length); + return buffer; + } + + @Override + public int getContentLength() { + int length = 0; + try { + length = inputStream.available(); + System.out.println("接收到的数据长度为 " + length); + } catch (IOException e) { + e.printStackTrace(); + } + return length; + } + + @Override + public void close() { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/group15/1507_977996067/src/task3/download/impl/ConnectionManagerImpl.java b/group15/1507_977996067/src/task3/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..3db283bc27 --- /dev/null +++ b/group15/1507_977996067/src/task3/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,23 @@ +package task3.download.impl; + + +import task3.download.api.Connection; +import task3.download.api.ConnectionException; +import task3.download.api.ConnectionManager; + +import java.io.FileInputStream; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + ConnectionImpl connection = null; + try { + connection = new ConnectionImpl(new FileInputStream("f://pictures/b3.jpg")); + } catch (Exception e) { + e.printStackTrace(); + } + return connection; + } + +} diff --git a/group15/1507_977996067/src/task3/linkedlist/MyLinkedList.java b/group15/1507_977996067/src/task3/linkedlist/MyLinkedList.java new file mode 100644 index 0000000000..14092d3ae9 --- /dev/null +++ b/group15/1507_977996067/src/task3/linkedlist/MyLinkedList.java @@ -0,0 +1,286 @@ +package task3.linkedlist; + +import java.util.Iterator; + +public class MyLinkedList> { + + //存放的元素数量 + private int size; + + private Node head; + + public MyLinkedList() { + head = new Node<>(null, null); + } + + public void add(T o) { + add(size, o); + } + + public void add(int index, T o) { + if (index < 0 || index > size) + throw new IndexOutOfBoundsException("index " + index + " 不合法"); + Node targetNode = new Node<>(null, o); + Node targetPrevNode = getPrevNode(index); + targetNode.next = targetPrevNode.next; + targetPrevNode.next = targetNode; + size++; + } + + public T get(int index) { + checkIndexRange(index); + return getPrevNode(index).next.data; + } + + public Node getNode(int index) { + checkIndexRange(index); + return getPrevNode(index).next; + } + + + public T remove(int index) { + checkIndexRange(index); + Node prevNode = getPrevNode(index); + Node nodeToRemove = prevNode.next; + prevNode.next = nodeToRemove.next; + size--; + return nodeToRemove.data; + } + + public int size() { + return size; + } + + public void addFirst(T o) { + add(0, o); + + } + + public void addLast(T o) { + add(size, o); + } + + public T removeFirst() { + return remove(0); + } + + public T removeLast() { + return remove(size - 1); + } + + + public Iterator iterator() { + return new MyLinkedItr(); + } + + /** + * 找到位置为index的前一个node + * + * @param index 索引值 + */ + + private Node getPrevNode(int index) { + Node targetPrevNode = head; + for (int i = 0; i < index; i++) { + targetPrevNode = targetPrevNode.next; + } + return targetPrevNode; + } + + /** + * 检查索引是否越界 + * + * @param index 索引值 + */ + private void checkIndexRange(int index) { + if (index < 0 || index >= size) + throw new IndexOutOfBoundsException("index " + index + " 越界"); + } + + private static class Node { + private Node next; + private T data; + + private Node(Node next, T data) { + this.next = next; + this.data = data; + } + } + + private class MyLinkedItr implements Iterator { + + private Node currentNode = head; + + @Override + public boolean hasNext() { + return currentNode.next != null; + } + + @Override + public T next() { + Node nextNode = currentNode.next; + T data = nextNode.data; + currentNode = nextNode; + return data; + } + + @Override + public void remove() { + currentNode.next = currentNode.next.next; + } + } + + @Override + public String toString() { + if (size == 0) + return "[]"; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < size; i++) { + sb.append(get(i)).append(","); + } + return sb.substring(0, sb.length() - 1); + } + + /** + * ================================== + * 3.12作业 + * ================================== + *

+ * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (size == 0) + return; + int length = size; + for (int i = length - 1; i >= 0; i--) { + add(get(i)); + } + remove(0, length); // :( + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + remove(0, size / 2); + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + */ + public void remove(int i, int length) { + if (length == 0) + return; + if (i + length > size) + throw new IndexOutOfBoundsException("长度不够"); + Node startNode = getPrevNode(i); + startNode.next = (i + length == size) ? null : getNode(i + length); + size -= length; + } + + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + */ + @SuppressWarnings("unchecked") + public T[] getElements(MyLinkedList list) { + int size = list.size(); + Comparable[] result = new Comparable[size]; + int count = 0; + for (int i = 0; i < size; i++) { + result[count++] = get(list.get(i)); + } + return (T[]) result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + */ + + public void subtract(MyLinkedList list) { + int length = list.size(); + for (int i = 0; i < length; i++) { + for (int j = 0; j < size; j++) { + if (get(j).equals(list.get(i))) { + remove(j); + break; + } + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + Iterator iterator = iterator(); + int pos = 0; + while (iterator.hasNext()) { + //当前索引的值等于下一个索引的值时,就把当前索引删掉 + if (get(pos).equals(get(pos + 1))) { + remove(pos); + } + pos++; + iterator.next(); + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + */ + public void removeRange(T min, T max) { + if (min.compareTo(max) >= 0) + throw new RuntimeException("Are you kidding me ?"); + int minIndex = 0; + int maxIndex = size; + for (int i = 0; i < size; i++) { + if (get(i).compareTo(min) > 0) { + minIndex = i; + break; + } + } + for (int i = size - 1; i >= 0; i--) { + if (get(i).compareTo(max) < 0) { + maxIndex = i; + break; + } + } + remove(minIndex, maxIndex - minIndex + 1); + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + */ + public MyLinkedList intersection(MyLinkedList list) { + MyLinkedList resultList = new MyLinkedList<>(); + int firstLength = size; + int secondLength = list.size(); + int firstPos = 0; + int secondPos = 0; + while (firstPos < firstLength && secondPos < secondLength) { + T firstItem = get(firstPos); + T secondItem = list.get(secondPos); + int compareResult = firstItem.compareTo(secondItem); + if (compareResult == 0) { + resultList.add(firstItem); + firstPos++; + secondPos++; + } else if (compareResult < 0) + firstPos++; + else + secondPos++; + } + return resultList; + } +} \ No newline at end of file diff --git a/group15/1507_977996067/src/task3/linkedlist/MyLinkedListTest.java b/group15/1507_977996067/src/task3/linkedlist/MyLinkedListTest.java new file mode 100644 index 0000000000..845960ff97 --- /dev/null +++ b/group15/1507_977996067/src/task3/linkedlist/MyLinkedListTest.java @@ -0,0 +1,135 @@ +package task3.linkedlist; + +import org.junit.Test; + +import java.util.Arrays; + +public class MyLinkedListTest { + + @Test + public void testReverse() { + MyLinkedList list = new MyLinkedList<>(); + list.add(3); + list.add(7); + list.add(10); + System.out.println(list); + list.reverse(); + System.out.println(list); + } + + @Test + public void testRemoveFirstHalf() { + MyLinkedList list = new MyLinkedList<>(); + list.add(2); + list.add(5); + list.add(7); + list.add(8); + list.add(10); + System.out.println(list); + list.removeFirstHalf(); + System.out.println(list); + } + + @Test + public void testRemove() { + MyLinkedList list = new MyLinkedList<>(); + list.add(3); + list.add(7); + list.add(10); + System.out.println(list); + list.remove(2, 1); + System.out.println(list); + } + + @Test + public void testGetElements() { + MyLinkedList list = new MyLinkedList<>(); + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + MyLinkedList listB = new MyLinkedList<>(); + listB.add(1); + listB.add(3); + listB.add(4); + listB.add(6); + Arrays.stream(list.getElements(listB)).forEach(System.out::println); + } + + @Test + public void testSubtract() { + MyLinkedList list = new MyLinkedList<>(); + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + MyLinkedList listB = new MyLinkedList<>(); + listB.add(101); + listB.add(501); + listB.add(201); + listB.add(601); + list.subtract(listB); + System.out.println(list); + } + + @Test + public void testRemoveDuplicateValues() { + MyLinkedList list = new MyLinkedList<>(); + list.add(11); + list.add(11); + list.add(201); + list.add(301); + list.add(401); + list.add(401); + list.add(601); + list.add(601); + list.removeDuplicateValues(); + System.out.println(list); + } + + @Test + public void testRemoveRange() { + MyLinkedList list = new MyLinkedList<>(); + 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(10,101); + System.out.println(list); + } + + @Test + public void testIntersection() { + MyLinkedList list = new MyLinkedList<>(); + list.add(11); + list.add(101); + list.add(201); + list.add(301); + list.add(401); + list.add(501); + list.add(601); + list.add(701); + + MyLinkedList listB = new MyLinkedList<>(); + listB.add(101); + listB.add(201); + listB.add(501); + listB.add(601); + listB.add(701); + System.out.println(list.intersection(listB)); + } +} diff --git a/group15/1507_977996067/src/task4/loader/ClassFileLoader.java b/group15/1507_977996067/src/task4/loader/ClassFileLoader.java new file mode 100644 index 0000000000..5b93ed09fe --- /dev/null +++ b/group15/1507_977996067/src/task4/loader/ClassFileLoader.java @@ -0,0 +1,49 @@ +package task4.loader; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList<>(); + + public byte[] readBinaryCode(String className) { + boolean validClassName = className.endsWith(".class"); + className = className.replaceAll("\\.", "/"); + if (!validClassName) { + className += ".class"; + } else { + className = className.replace("/class", ".class"); + } + for (String clzPath : clzPaths) { + if (!clzPath.endsWith("/")) + clzPath += "/"; + try { + FileInputStream stream = new FileInputStream(clzPath + className); + byte[] buffer = new byte[stream.available()]; + while (stream.read(buffer) != -1) { + } + return buffer; + } catch (IOException e) { + continue; + } + } + return null; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + StringBuilder sb = new StringBuilder(); + for (String clzPath : clzPaths) { + sb.append(clzPath).append(";"); + } + return sb.substring(0, sb.length() - 1); + } + +} \ No newline at end of file diff --git a/group15/1507_977996067/src/task4/loader/ClassFileloaderTest.java b/group15/1507_977996067/src/task4/loader/ClassFileloaderTest.java new file mode 100644 index 0000000000..4f6e8ede0f --- /dev/null +++ b/group15/1507_977996067/src/task4/loader/ClassFileloaderTest.java @@ -0,0 +1,79 @@ +package task4.loader; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassFileloaderTest { + + + static String path1 = "E:/Idea/coding2017/group15/1507_977996067/out/"; + 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 = "task4.loader.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1034, byteCodes.length); + + } + + + @Test + public void testMagicNumber() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "task4.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 < 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/group15/1507_977996067/src/task4/loader/EmployeeV1.java b/group15/1507_977996067/src/task4/loader/EmployeeV1.java new file mode 100644 index 0000000000..00a6683dda --- /dev/null +++ b/group15/1507_977996067/src/task4/loader/EmployeeV1.java @@ -0,0 +1,29 @@ +package task4.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(); + + } +} diff --git a/group15/1507_977996067/src/task4/lru/LRUPageFrame.java b/group15/1507_977996067/src/task4/lru/LRUPageFrame.java new file mode 100644 index 0000000000..9dfa1a66a0 --- /dev/null +++ b/group15/1507_977996067/src/task4/lru/LRUPageFrame.java @@ -0,0 +1,122 @@ +package task4.lru; + +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + public Node(Node prev, Node next, int pageNum) { + this.prev = prev; + this.next = next; + this.pageNum = pageNum; + } + } + + 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) { + if (size == 0) { + last = first = new Node(first, last, pageNum); +// last = new Node(first, null, pageNum); + size++; + } else if (size > 0 && size < capacity) { + Node _node = get(pageNum); + if (_node == null) { + Node newNode = new Node(null, first, pageNum); + first.prev = newNode; + first = newNode; + clear(); + size++; + } else { + exchange(_node); + } + } else { + Node _node = get(pageNum); + if (_node == null) { + last = last.prev; + Node newNode = new Node(null, first, pageNum); + first.prev = newNode; + first = newNode; + clear(); + } else exchange(_node); + } + } + + private void exchange(Node node) { + Node nextNode = node.next; + Node prevNode = node.prev; + if (prevNode == null) + return;//头部的话什么都不用做 + if (nextNode != null) { + nextNode.prev = prevNode; + prevNode.next = nextNode; + last = getLast(nextNode); + } else { + last = prevNode; + } + first.prev = node; + node.next = first; + first = node; + clear(); + } + + private void clear() { + last.next = null; + first.prev = null; + } + + private Node getLast(Node startNode) { + Node currentNode = startNode; + while (currentNode.next != null) { + currentNode = currentNode.next; + } + return currentNode; + } + + private Node get(int pageNum) { + Node currentNode = last; + for (int i = 0; i < size; i++) { + if (pageNum == currentNode.pageNum) { + return currentNode; + } + currentNode = currentNode.prev; + } + 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(); + } + +} \ No newline at end of file diff --git a/group15/1507_977996067/src/task4/lru/LRUPageFrameTest.java b/group15/1507_977996067/src/task4/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..e4567f92e0 --- /dev/null +++ b/group15/1507_977996067/src/task4/lru/LRUPageFrameTest.java @@ -0,0 +1,29 @@ +package task4.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/group15/1510_739253131/README.md b/group15/1510_739253131/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group15/1510_739253131/demo1.jpg b/group15/1510_739253131/demo1.jpg new file mode 100644 index 0000000000..e69de29bb2 diff --git a/group15/1510_739253131/src/com/bruce/homework0226/ArrayListV00.java b/group15/1510_739253131/src/com/bruce/homework0226/ArrayListV00.java index 3137c7568b..d45544c837 100644 --- a/group15/1510_739253131/src/com/bruce/homework0226/ArrayListV00.java +++ b/group15/1510_739253131/src/com/bruce/homework0226/ArrayListV00.java @@ -4,18 +4,19 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Objects; /** * 用数组实现ArrayList基本功能:add,remove,size,contains,toArray方法 - * @Version: 0.0 + * @Version: 0.1 * Created by Bruce.Jiao on 17-2-23. */ -public class ArrayListV00 implements Serializable { +public class ArrayListV00 implements Serializable { /** * 存放集合元素的数组 */ - private transient Object[] elementData; + private Object[] elementData; /** * 集合中元素的个数 */ @@ -34,9 +35,9 @@ public ArrayListV00() throws MyException { * @param initCapacity * 用户传入的集合大小,底层数组的初始化大小 */ - public ArrayListV00(int initCapacity) throws MyException{ + public ArrayListV00(int initCapacity) { if(initCapacity < 0){ - throw new MyException("集合大小不能小于0"); + //throw new MyException("集合大小不能小于0"); } elementData = new Object[initCapacity]; } @@ -48,13 +49,30 @@ public ArrayListV00(int initCapacity) throws MyException{ * 添加的元素,允许添加null * @return true:添加成功 ; false:添加失败 */ - public boolean add(Object value) { - // 添加元素之前,对数组长度进行判断,此处需要传入当前元素个数+1, + public boolean add(T value) { ensureCapacity(size + 1); elementData[size++] = value; return true; } + public void add(int index, T value) { + if(index < 0 || index > size) { + //抛出异常 + } + ensureCapacity(size+1); + System.arraycopy(elementData, index, elementData, index+1 , size-index); + elementData[index] = value; + size++; + } + + public T set(int index, T value) { + if(index < 0 || index > size) { + return null;//抛出异常 + } + elementData[index] = value; + return value; + } + /** * 返回指定位置的元素 数组和集合,下标从1开始 * @@ -62,13 +80,14 @@ public boolean add(Object value) { * 用户指定的位置 * @return */ - public Object get(int index) throws MyException { + @SuppressWarnings("unchecked") + public T get(int index) { // 判断是否越界,注意:此处判断依据是size,而不能是elementData.length, // 集合元素个数size小于等于elementData.length if (index >= size || index < 0) { - throw new MyException("给定数值超出集合范围"); + return null;//throw new MyException("给定数值超出集合范围"); } - return elementData[index]; + return (T) elementData[index]; } /** @@ -78,11 +97,11 @@ public Object get(int index) throws MyException { * 用户指定位置,从0开始 * @return 返回删除掉的指定位置的元素 */ - public Object remove(int index) throws MyException { + public T remove(int index) { if (index >= size || index < 0) { - throw new MyException("给定数值超出集合范围"); + return null;//throw new MyException("给定数值超出集合范围"); } - Object value = elementData[index]; + T value = (T) elementData[index]; // 数组中被删除元素后边的所有元素的个数,此处不能使用elementData.length int length = size - 1 - index; // 被删除位置后还有元素,将数组中被删除位置往后(不包含被删除位置)的所有元素往前移动一位 @@ -93,23 +112,53 @@ public Object remove(int index) throws MyException { return value; } + /** + * 删除元素 + * @Version:0.1 + * @return true:删除成功;false:删除失败 + */ + public boolean remove(T value) { + int index = indexOf(value); + if (index < 0) { + return false; + } + System.arraycopy(elementData, index+1, elementData, index, elementData.length-1-index); + elementData[size--] = null; + return true; + } + + public int indexOf(T value) { + for(int i = 0 ; i < elementData.length ; i++){ + if(Objects.equals(elementData[i], value)) { + return i; + } + } + return -1; + } + /** * 判断集合中是否包含指定的元素 - * * @param value * 用户制定的元素 * @return true:包含指定元素;false:不包含指定元素 */ public boolean contains(Object value) { - for (int i = 0; i < elementData.length; i++) { - if (value == null) { - if (elementData[i] == null) { - return true; - } - } else { - if (value.equals(elementData[i])) { - return true; - } + //v0.0版本 +// for (int i = 0; i < elementData.length; i++) { +// if (value == null) { +// if (elementData[i] == null) { +// return true; +// } +// } else { +// if (value.equals(elementData[i])) { +// return true; +// } +// } +// } + //v0.1版本,根据老师作业讲解进行修改 + for(Object o : elementData) { + if (Objects.equals(o,value)) { + return true; } } return false; @@ -117,9 +166,9 @@ public boolean contains(Object value) { /** * 得到集合对应的静态数组 - * * @return 底层数组 */ + @SuppressWarnings("unchecked") public Object[] toArray() { //elementData可能会包含null元素,不能直接返回,需返回一个包含集合所有元素的新数组 // return elementData; @@ -135,6 +184,41 @@ public int size() { return size; } + public boolean isEmpty() { + return size == 0; + } + + public void clear() { + for (int i = 0 ; i < size ; i++) { + elementData[i] = null; + } + size = 0; + } + + public IteratorV00 iterator() { + return new Iterator(); + } + + //非静态内部类,和外部类实例绑定的,可以访问实例方法和属性 + private class Iterator implements IteratorV00 { + private int position; + + Iterator(){} + + @Override + public boolean hasNext() { + return position < size; + } + + @Override + public T next() { + if(hasNext()){ + return get(position++); + } + return null; + } + } + /** * 传入的数值与数组长度进行比较,长度小于传入数值,对数组进行扩容 * @@ -147,14 +231,17 @@ public void ensureCapacity(int minCapacity) { if (minCapacity > oldCapacity) { // 此处用新的局部变量引用指向原有数组的内存地址,仅为了避免复制数组元素到新数组时候,发生原有数组内存地址被覆盖的情况 Object[] oldArray = elementData; - // 先得到现有数组长度1.5倍的值 - int newCapacity = oldCapacity + oldCapacity >> 1; - // 如果增加1.5倍后的数值仍然小于传入的数值,将传入的数值赋给新数组长度 - if (minCapacity > newCapacity) { - newCapacity = minCapacity; - } - // 将elementData引用指向一个新的扩容后的数组,并且将原有数组的元素复制到新数组中 - elementData = Arrays.copyOf(elementData, newCapacity); +//v0.0初級版本 +// int newCapacity = oldCapacity + oldCapacity >> 1; +// if (minCapacity > newCapacity) { +// newCapacity = minCapacity; +// } +// elementData = Arrays.copyOf(elementData, newCapacity); + //v0.1升級版本 + int newCapacity = Math.max(minCapacity, oldCapacity + oldCapacity >> 1); + Object[] newElementData = new Object[newCapacity]; + System.arraycopy(elementData,0,newElementData,0,oldCapacity); + elementData = newElementData; } } diff --git a/group15/1510_739253131/src/com/bruce/homework0226/BinaryTreeNode.java b/group15/1510_739253131/src/com/bruce/homework0226/BinaryTreeNode.java new file mode 100644 index 0000000000..b86aa85995 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0226/BinaryTreeNode.java @@ -0,0 +1,108 @@ +package com.bruce.homework0226; + +public class BinaryTreeNode { + + private T data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public BinaryTreeNode(){} + + public T getData() { + return data; + } + public void setData(T 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; + } + + @SuppressWarnings("unchecked") + public BinaryTreeNode insert(T data){ + if(this.data == null){ + this.data = data; + return this; + } + if(this.data.compareTo(data) > 0) { + if(this.left == null) { + this.left = new BinaryTreeNode(); + this.left.data = data; + return this.left; + } else { + return this.left.insert(data); + } + } else if(this.data.compareTo(data) < 0) { + if(this.right == null) { + this.right = new BinaryTreeNode(); + this.right.data = data; + return this.right; + } else { + return this.right.insert(data); + } + } else { + return this; + } + } + + @SuppressWarnings("unchecked") + public BinaryTreeNode search(T data){ + if(data == null || this.data == null) { + return null; + } + if(this.data.compareTo(data) > 0) { + if(this.left == null) { + return null; + } else { + return this.left.search(data); + } + } else if(this.data.compareTo(data) < 0) { + if(this.right == null) { + return null; + } else { + return this.right.search(data); + } + } else { + return this; + } + } + + //TODO 未确定 + @SuppressWarnings("unchecked") + public BinaryTreeNode delete(T data){ + BinaryTreeNode treeNode = search(data); + if(treeNode == null) { + return null; + } + if(this.data.compareTo(data) > 0) { + return this.left.delete(data); + } else if(this.data.compareTo(data) < 0) { + return this.right.delete(data); + } else { + if(this.left == null) { + if(this.right == null) { + this.data = null; + } else { + this.right = this; + } + } else { + if(this.right == null) { + this.left = this; + } else { + this.left = this; + this.left.right = this.right; + } + } + } + return this; + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0226/IteratorV00.java b/group15/1510_739253131/src/com/bruce/homework0226/IteratorV00.java new file mode 100644 index 0000000000..1f409bd9ad --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0226/IteratorV00.java @@ -0,0 +1,9 @@ +package com.bruce.homework0226; + +/** + * Created by Bruce.Jiao on 2017/3/5. + */ +public interface IteratorV00 { + public boolean hasNext(); + public T next(); +} diff --git a/group15/1510_739253131/src/com/bruce/homework0226/JuintTest.java b/group15/1510_739253131/src/com/bruce/homework0226/JuintTest.java index b0aa452f6d..2110d2036e 100644 --- a/group15/1510_739253131/src/com/bruce/homework0226/JuintTest.java +++ b/group15/1510_739253131/src/com/bruce/homework0226/JuintTest.java @@ -33,8 +33,6 @@ public void testArrayList(){ System.out.println("集合为:"+ Arrays.toString(arrayList.toArray())); System.out.println("集合底层数组长度:"+ arrayList.arrayLength()); // System.out.println("集合下标-1处的元素:"+arrayList.get(-1)); - } catch (MyException e) { - System.out.println("发生异常>>>"+e); } catch (Exception e) { e.printStackTrace(); } diff --git a/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV00.java b/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV00.java index ddfa9dc1a8..485b6cfde8 100644 --- a/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV00.java +++ b/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV00.java @@ -4,7 +4,6 @@ import java.io.Serializable; import java.util.Arrays; -import java.util.Collection; /** * 实现LinkedList的基本功能 @@ -18,19 +17,21 @@ public class LinkedListV00 implements Serializable { private transient int size = 0; /** - * 前一个节点 + * 头节点 */ - private transient Node first; + private transient Node head; /** - * 后一个节点 + * 尾节点 */ private transient Node last; /** * 空构造 */ - public LinkedListV00(){} + public LinkedListV00(){ + head = new Node(null, null, null); + } /** * 添加一个节点 @@ -99,11 +100,11 @@ public Object[] toArray(){ */ private static class Node{ E element; - Node previous; + Node prev; Node next; - Node(Node previous,E element,Node next){ + Node(Node prev,E element,Node next){ this.element = element; - this.previous = previous; + this.prev = prev; this.next = next; } } @@ -118,7 +119,7 @@ private Node node(int index){ //如果index小于size的一半,即目标节点在链表前半部分 if(index < (size >> 1)){ //从第一个节点挨个向后查找,一直到(index-1)处,将其next赋值给x - x = first; + x = head; for(int i = 0; i node(int index){ //从最后一个节点挨个向前查找,一直查找到(index+1)处,将其previous赋值给x x = last; for(int i = size-1;i>index;i--){ - x = x.previous; + x = x.prev; } } //返回x @@ -148,7 +149,7 @@ private void linkNext(E e){ //如果n为null,说明还是一个空的双向链表,将新节点newNode赋值给first //否则,将newNode赋值给n的next if(n == null){ - first = newNode; + head = newNode;//第一次添加的时候,将该元素放在头节点位置 }else{ n.next = newNode; } @@ -167,16 +168,16 @@ private E unlink(Node node){ //拿到传入节点的next节点 final Node next = node.next; //拿到传入节点的previous节点 - final Node previous = node.previous; + final Node previous = node.prev; //如果传入节点的previous=null,说明是第一个节点 if(previous == null){ //将链表第一个节点指向本节点的下一个节点next,即把原有的第一个节点解除 - first = next; + head = next; }else{ //将本节点前一个节点的next指向本节点后一个节点,即跳过了本节点 previous.next = next; //将本节点的previous节点设置为null - node.previous = null; + node.prev = null; } //如果传入节点的next=null,说明是最后一个节点 if(next == null){ @@ -184,7 +185,7 @@ private E unlink(Node node){ last = previous; }else{ //将本节点下一个节点的previous节点指向本节点的前一个节点,即跳过了本节点 - next.previous = previous; + next.prev = previous; //本节点的next节点设置为null node.next = null; } diff --git a/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV01.java b/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV01.java new file mode 100644 index 0000000000..f4defc7d3f --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0226/LinkedListV01.java @@ -0,0 +1,139 @@ +package com.bruce.homework0226; + +import java.util.Objects; + +public class LinkedListV01 { + private int size; + private Node head; + private Node last; + + public LinkedListV01() { + //保证了初始化一个对象的时候,头节点不为空 + this.head = new Node(null); + } + + public boolean add (T element) { + //双向链表,双向都需要维护 + if(last == null){ + last = new Node<>(element); + head.next = last; + last.pre = head; + }else{ + Node oldLast = last; + last = new Node<>(element); + last.pre = oldLast; + oldLast.next = last; + } + size++; + return true; + } + + public boolean add(int index, T element) { + Node node = getNode(index); + Node newNode = new Node(element); + Node pre = node.pre; + pre.next = newNode; + newNode.pre = pre; + newNode.next = node; + size++; + return true; + } + + public boolean remove(T element){ + Node node = head; + //下一个节点不为null + while(node.next != null){ + node = node.next; + if(Objects.equals(node.element, element)){ + if(node.next != null){ + node.next.pre = node.pre; + } + node.pre.next = node.next; + size--; + return true; + } + } + //下一个节点为null,说明是尾节点 + if(node != head){ + last = node; + } + //head.next=null,说明是一个空的链表,即仅有一个空head节点 + return false; + } + + public T remove(int index){ + Node node = getNode(index); + Node pre = node.pre; + Node next = node.next; + pre.next = next; + next.pre = pre; + size--; + return node.element; + } + + public void clear(){ + for(Node x = head; x != null; ){ + Node next = x.next; + x.pre = null; + x.next = null; + x.element = null; + } + head = last = null; + size = 0; + } + + public int size(){ + return size; + } + + public boolean isEmpty(){ + return size == 0; + } + + public boolean contains(Object o){ + for(int i = 0; i < size; i++){ + if(Objects.equals(getNode(i).element, o)){ + return true; + } + } + return false; + } + + public Node getNode(int index){ + if(index < 0 || index >size){ + return null; + } + Node node = head; + for(int i = 0; i < index; i++){ + node = node.next; + } + return node; + } + + public T get(int index) { + return getNode(index).element; + } + + public int indexOf(T element){ + Node node = head; + int index = 0; + while(node.next != null){ + node = node.next; + if(Objects.equals(node.element, element)){ + return index; + } + index++; + } + return -1; + } + + private static class Node { + T element; + Node pre; + Node next; + + Node(T element) { + this.element = element; + } + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0226/StackV00.java b/group15/1510_739253131/src/com/bruce/homework0226/StackV00.java index 29cfe7e9fd..900df94251 100644 --- a/group15/1510_739253131/src/com/bruce/homework0226/StackV00.java +++ b/group15/1510_739253131/src/com/bruce/homework0226/StackV00.java @@ -10,7 +10,7 @@ * @Version: 0.0 * Created by Bruce.Jiao on 17-2-24. */ -public class StackV00 implements Serializable{ +public class StackV00 implements Serializable{ /** * 底层存放栈元素的数组 @@ -61,7 +61,7 @@ public StackV00(int initCapacity, int capacityIncrement) throws MyException{ * @param value 添加的元素,可以为null * @return 添加成功后的元素 */ - public Object push(Object value){ + public T push(T value){ ensureCapacity(size+1); //将新增的元素放在size索引处,并且将size加1 elementData[size++] = value; @@ -72,9 +72,11 @@ public Object push(Object value){ * 从栈中获取元素,拿到当前所有元素中最后添加进来的元素 * @return 最后的元素 */ - public Object pop(){ + public T pop(){ //拿到最后的元素,在栈中将该元素删除,将size减1 - return elementData[--size]; + T data = (T) elementData[size-1]; + elementData[size--] = null; + return data; } /** diff --git a/group15/1510_739253131/src/com/bruce/homework0305/array/JuintArrayUtil.java b/group15/1510_739253131/src/com/bruce/homework0305/array/JuintArrayUtil.java index eb5487e76d..8b766870d9 100644 --- a/group15/1510_739253131/src/com/bruce/homework0305/array/JuintArrayUtil.java +++ b/group15/1510_739253131/src/com/bruce/homework0305/array/JuintArrayUtil.java @@ -9,11 +9,17 @@ /** * Created by Bruce.Jiao on 2017/3/2. */ -public class JuintArrayUtil extends TestCase { +public class JuintArrayUtil { + + ArrayUtil au; + + @Before + public void init(){ + au = new ArrayUtil(); + } @Test public void testReverse(){ - ArrayUtil au = new ArrayUtil(); int[] demo0 = {}; int[] demo1 = {6}; int[] demo = {7, 9, 30, 3, 4, 6}; @@ -29,7 +35,6 @@ public void testReverse(){ @Test public void testRemoveZero(){ - ArrayUtil au = new ArrayUtil(); int[] one = {0}; int[] many = {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; System.out.println(Arrays.toString(au.removeZero(one))); @@ -40,7 +45,6 @@ public void testRemoveZero(){ @Test public void testMerge(){ - ArrayUtil au = new ArrayUtil(); int[] arr1 = {3,4,5,6,7,8,9}; int[] arr2 = {1,3,5,6,7,9,10,12,13}; int[] arr3 = null; @@ -52,32 +56,27 @@ public void testMerge(){ @Test public void testGrow(){ - ArrayUtil au = new ArrayUtil(); int[] arr = {3,4,5,6,7,8,9}; System.out.println(Arrays.toString(au.grow(arr,5))); } @Test public void testFibonacci(){ - ArrayUtil au = new ArrayUtil(); System.out.println(Arrays.toString(au.fibonacci(15))); } @Test public void testPrimes(){ - ArrayUtil au = new ArrayUtil(); System.out.println(Arrays.toString(au.getPrimes(23))); } @Test public void testPerfectNumbers(){ - ArrayUtil au = new ArrayUtil(); - System.out.println(Arrays.toString(au.getPerfectNumbers(23))); + System.out.println(Arrays.toString(au.getPerfectNumbers(Integer.MAX_VALUE))); } @Test public void testJoin(){ - ArrayUtil au = new ArrayUtil(); int[] array = {1,6,8,8,8,8,8,8,8,8,8,}; System.out.println(au.join(array,"-")); } diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/Configuration.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/Configuration.java new file mode 100644 index 0000000000..a703c5a1a3 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/Configuration.java @@ -0,0 +1,106 @@ +package com.bruce.homework0305.demostruts; + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 用来存放解析后的struts.xml数据 + */ +public class Configuration { + + private Map actionConfigMap = new HashMap<>(); + + public Configuration(String fileName){ + try { + //拿到当前类的报名,拼接出struts.xml的路径,将文件读到输入流 + String path = this.getClass().getPackage().getName(); + path = path.replace(".", "/"); + InputStream is = this.getClass().getResourceAsStream("/" + path + "/" + fileName); + //对输入流进行解析 + parseXml(is); + is.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + //用Jdom解析xml + private void parseXml(InputStream is) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(is); + Element root = document.getRootElement(); + List actions = root.getChildren("action"); + for(Element element: actions) { + String actionName = element.getAttributeValue("name"); + String actionClz = element.getAttributeValue("class"); + ActionConfig ac = new ActionConfig(actionName, actionClz); + List results = element.getChildren("result"); + for(Element result: results) { + String resultName = result.getAttributeValue("name"); + String resultJsp = result.getValue(); + ac.addViewResult(resultName, resultJsp); + } + actionConfigMap.put(actionName, ac); + } + } catch (JDOMException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 通过action的name值拿到对应的class路径 + * @param actionName + * @return + */ + public String getClassName(String actionName) { + return actionConfigMap.get(actionName).getClassName(); + } + + /** + * 根据action的name值和result的name值,拿到对应的jsp路径 + * @param actionName + * @param resultName + * @return + */ + public String getResultView(String actionName, String resultName) { + return actionConfigMap.get(actionName).getViewName(resultName); + } + + /** + * 内部静态类,用来存放struts.xml解析出来的action信息 + */ + private static class ActionConfig{ + private String name; + private String clz; + Map results = new HashMap<>(); + + public ActionConfig(String actionName,String clzName){ + this.name = actionName; + this.clz = clzName; + } + + public void addViewResult(String resultName, String jspName){ + results.put(resultName, jspName); + } + + public String getClassName() { + return clz; + } + + public String getViewName(String resultName) { + return results.get(resultName); + } + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ConfigurationTest.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ConfigurationTest.java new file mode 100644 index 0000000000..5de7ad7095 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ConfigurationTest.java @@ -0,0 +1,29 @@ +package com.bruce.homework0305.demostruts; + +import org.junit.Assert; +import org.junit.Test; + +public class ConfigurationTest { + + Configuration cfg = new Configuration("struts.xml"); + @Test + public void testGetClassName(){ + String login = cfg.getClassName("login"); + Assert.assertEquals("com.bruce.homework0305.demostruts.LoginAction",login); + String logout = cfg.getClassName("logout"); + Assert.assertEquals("com.bruce.homework0305.demostruts.LoginAction",login); + } + + @Test + public void getResultView(){ + String resultView = cfg.getResultView("login", "success"); + Assert.assertEquals("/jsp/homepage.jsp",resultView); + String resultView1 = cfg.getResultView("login", "fail"); + Assert.assertEquals("/jsp/showLogin.jsp",resultView1); + String resultView2 = cfg.getResultView("logout", "success"); + Assert.assertEquals("/jsp/welcome.jsp",resultView2); + String resultView3 = cfg.getResultView("logout", "error"); + Assert.assertEquals("/jsp/error.jsp",resultView3); + } + +} diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/LoginAction.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/LoginAction.java new file mode 100644 index 0000000000..7c1c8c8962 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/LoginAction.java @@ -0,0 +1,39 @@ +package com.bruce.homework0305.demostruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @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/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtil.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtil.java new file mode 100644 index 0000000000..de3f13f9b0 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtil.java @@ -0,0 +1,65 @@ +package com.bruce.homework0305.demostruts; + +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 ReflectUtil { + + public static List getSetterMethods(Class clz){ + return getMethods(clz, "set"); + } + + public static List getGetterMethods(Class clz){ + return getMethods(clz, "get"); + } + + public static void setParameters(Object o, Map params){ + List setterMethods = getSetterMethods(o.getClass()); + for(Method method: setterMethods) { + for(String name: params.keySet()) { + if(method.getName().equalsIgnoreCase("set"+name)) { + try { + method.invoke(o, params.get(name)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } + + public static Map getParameters(Object o) { + Map parameterMap = new HashMap<>(); + List getterMethods = getGetterMethods(o.getClass()); + for(Method method : getterMethods) { + String methodName = method.getName(); + String parameterName = methodName.replace("get","").toLowerCase(); + try { + Object value = method.invoke(o); + parameterMap.put(parameterName, value); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + return parameterMap; + } + + private static List getMethods(Class clz, String methodStart){ + List methods = new ArrayList<>(); + Method[] declaredMethods = clz.getDeclaredMethods(); + for (Method method: declaredMethods) { + if(method.getName().startsWith(methodStart)) { + methods.add(method); + } + } + return methods; + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtilTest.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtilTest.java new file mode 100644 index 0000000000..3e4a380548 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/ReflectUtilTest.java @@ -0,0 +1,51 @@ +package com.bruce.homework0305.demostruts; + +import junit.framework.Assert; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReflectUtilTest { + + @Test + public void testGetSetterMethods() throws Exception{ + String name = "com.bruce.homework0305.demostruts.LoginAction"; + Class aClass = Class.forName(name); + List setterMethods = ReflectUtil.getSetterMethods(aClass); + List expectNames = new ArrayList<>(); + expectNames.add("setName"); + expectNames.add("setPassword"); + List acctualNames = new ArrayList<>(); + for(Method method: setterMethods) { + acctualNames.add(method.getName()); + } + Assert.assertTrue(acctualNames.containsAll(expectNames)); + } + + @Test + public void testSetParameters() throws Exception{ + String name = "com.bruce.homework0305.demostruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + Map params = new HashMap<>(); + params.put("name","test"); + params.put("password","1234"); + ReflectUtil.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)); + } + + public void testGetParameters() throws Exception{ + String name = "com.bruce.homework0305.demostruts.LoginAction"; + Class clz = Class.forName(name); + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/Struts.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/Struts.java new file mode 100644 index 0000000000..bbdc51166f --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/Struts.java @@ -0,0 +1,53 @@ +package com.bruce.homework0305.demostruts; + +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; + + +public class Struts { + + private static final Configuration cfg = new Configuration("struts.xml"); + + public static View runAction(String actionName, Map parameters) throws DocumentException, + ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, 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字段中。 + */ + + String className = cfg.getClassName(actionName); + if(className == null){ + return null; + } + Class clz = Class.forName(className); + Object action = clz.newInstance(); + ReflectUtil.setParameters(action, parameters); + Method execute = clz.getDeclaredMethod("execute"); + String resultName = (String) execute.invoke(action); + String resultView = cfg.getResultView(actionName,resultName); + Map params = ReflectUtil.getParameters(action); + View view = new View(); + view.setJsp(resultView); + view.setParameters(params); + return view; + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/StrutsTest.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/StrutsTest.java new file mode 100644 index 0000000000..8726636484 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/StrutsTest.java @@ -0,0 +1,66 @@ +package com.bruce.homework0305.demostruts; + +import org.dom4j.DocumentException; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + try { + 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")); + } catch (DocumentException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + + @Test + public void testLoginActionFailed() { + try { + 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")); + } catch (DocumentException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0305/demostruts/View.java b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/View.java new file mode 100644 index 0000000000..4fb2eb99c5 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0305/demostruts/View.java @@ -0,0 +1,23 @@ +package com.bruce.homework0305.demostruts; + +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/group15/1510_739253131/src/com/bruce/homework0312/download/DownloadThread.java b/group15/1510_739253131/src/com/bruce/homework0312/download/DownloadThread.java new file mode 100644 index 0000000000..2a75d99919 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/DownloadThread.java @@ -0,0 +1,44 @@ +package com.bruce.homework0312.download; + +import com.bruce.homework0312.download.api.Connection; + +import java.io.IOException; +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; + 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(){ + 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) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloader.java b/group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloader.java new file mode 100644 index 0000000000..1708b38c3f --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloader.java @@ -0,0 +1,111 @@ +package com.bruce.homework0312.download; + +import com.bruce.homework0312.download.api.Connection; +import com.bruce.homework0312.download.api.ConnectionException; +import com.bruce.homework0312.download.api.ConnectionManager; +import com.bruce.homework0312.download.api.DownloadListener; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + + +public class FileDownloader { + + private String url; + + private String localFile; + + private DownloadListener listener; + + private ConnectionManager cm; + + private static final int DOWNLOAD_THREAD_COUNT = 3; + + public FileDownloader(String _url, String localFile) { + this.url = _url; + this.localFile = localFile; + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_THREAD_COUNT, new Runnable() { + @Override + public void run() { + listener.notifyFinished(); + } + }); + + Connection conn = null; + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + createPlaceHolderFile(this.localFile, length); + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_COUNT, length); + for (int i = 0; i < DOWNLOAD_THREAD_COUNT; i++) { + DownloadThread thread = new DownloadThread(conn, ranges[i][0], ranges[i][1], localFile, barrier); + thread.start(); + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + } + + //创建一个大小为length的空文件,准备存放下载内容 + private void createPlaceHolderFile(String localFile, int length) throws IOException { + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + for (int i = 0; i < length; i++) { + file.write(0); + } + file.close(); + } + + //根据文件总长度和下载的线程数量,“切分”文件 + private int[][] allocateDownloadRange (int threadCount, int totalLength) { + //二维数组第二维长度为2,用于存放startPos和endPo + int[][] ranges = new int[threadCount][2]; + int perLen = totalLength / threadCount; + int left = totalLength % threadCount; + for (int i = 0; i < threadCount; i++) { + ranges[i][0] = i * perLen; + ranges[i][1] = (i+1) * perLen - 1; + if (i == (threadCount-1)) { + ranges[i][1] += left; + } + } + return ranges; + } + + 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/group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloaderTest.java b/group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloaderTest.java new file mode 100644 index 0000000000..c53b28c93d --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/FileDownloaderTest.java @@ -0,0 +1,49 @@ +package com.bruce.homework0312.download; + +import com.bruce.homework0312.download.api.ConnectionManager; +import com.bruce.homework0312.download.api.DownloadListener; +import com.bruce.homework0312.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png"; + String localFile = "F:/study/test.png"; + FileDownloader downloader = new FileDownloader(url, localFile); + 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/group15/1510_739253131/src/com/bruce/homework0312/download/api/Connection.java b/group15/1510_739253131/src/com/bruce/homework0312/download/api/Connection.java new file mode 100644 index 0000000000..0995f6856f --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.bruce.homework0312.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/group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionException.java b/group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionException.java new file mode 100644 index 0000000000..38963d6a64 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionException.java @@ -0,0 +1,9 @@ +package com.bruce.homework0312.download.api; + + +public class ConnectionException extends Exception { + + public ConnectionException(Exception e){ + super(e); + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionManager.java b/group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionManager.java new file mode 100644 index 0000000000..58a1df0b19 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/api/ConnectionManager.java @@ -0,0 +1,12 @@ +package com.bruce.homework0312.download.api; + +import java.io.IOException; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException, IOException; +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/download/api/DownloadListener.java b/group15/1510_739253131/src/com/bruce/homework0312/download/api/DownloadListener.java new file mode 100644 index 0000000000..af61b4bf77 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.bruce.homework0312.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionImpl.java b/group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..495cda5669 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionImpl.java @@ -0,0 +1,74 @@ +package com.bruce.homework0312.download.impl; + +import com.bruce.homework0312.download.api.Connection; +import com.bruce.homework0312.download.api.ConnectionException; + +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; + +class ConnectionImpl implements Connection{ + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException{ + try { + //根据字符串路径拿到一个URL对象 + url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream inputStream = httpConn.getInputStream(); + //跳过inputStream前startPos字节数据,但由于skip内部是从头读取并且跳过的,该方法达不到预期效果 +// inputStream.skip(startPos); + byte[] buffer = new byte[BUFFER_SIZE]; + int totalLen = endPos - startPos + 1; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + while (outputStream.size() < totalLen) { + //从输入流中读取最多buffer.length个字节,并将其存储在缓冲区数组buffer中 + int read = inputStream.read(buffer); + //读到文件末尾时,inputStream.read(buffer)返回-1 + if (read < 0) { + break; + } + //将buffer中从0开始到read个字节写入outputStream + outputStream.write(buffer, 0, read); + } + + if (outputStream.size() > totalLen) { + byte[] data = outputStream.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + return outputStream.toByteArray(); + } + + @Override + public int getContentLength() { + URLConnection conn; + try { + conn = url.openConnection(); + return conn.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + } + +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionManagerImpl.java b/group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..0872894be8 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,18 @@ +package com.bruce.homework0312.download.impl; + +import com.bruce.homework0312.download.api.Connection; +import com.bruce.homework0312.download.api.ConnectionException; +import com.bruce.homework0312.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 path) throws ConnectionException, IOException { + return new ConnectionImpl(path); + } + +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/linkedlist/LinkedListV02.java b/group15/1510_739253131/src/com/bruce/homework0312/linkedlist/LinkedListV02.java new file mode 100644 index 0000000000..0ae4c674c9 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/linkedlist/LinkedListV02.java @@ -0,0 +1,292 @@ +package com.bruce.homework0312.linkedlist; + +import com.bruce.homework0226.LinkedListV01; + +import java.util.Objects; + +public class LinkedListV02 { + private int size = 0; + private Node head; + private Node last; + + public LinkedListV02() { + //保证了初始化一个对象的时候,头节点不为空 + this.head = new Node(null); + } + + public boolean add (T element) { + //双向链表,双向都需要维护 + if(last == null){ + last = new Node<>(element); + head.next = last; + last.pre = head; + }else{ + Node oldLast = last; + last = new Node<>(element); + last.pre = oldLast; + oldLast.next = last; + } + size++; + return true; + } + + public boolean add(int index, T element) { + Node node = getNode(index); + Node newNode = new Node(element); + Node pre = node.pre; + pre.next = newNode; + newNode.pre = pre; + newNode.next = node; + size++; + return true; + } + + public boolean remove(T element){ + Node node = head; + //下一个节点不为null + while(node.next != null){ + node = node.next; + if(Objects.equals(node.element, element)){ + if(node.next != null){ + node.next.pre = node.pre; + } + node.pre.next = node.next; + size--; + return true; + } + } + //下一个节点为null,说明是尾节点 + if(node != head){ + last = node; + } + //head.next=null,说明是一个空的链表,即仅有一个空head节点 + return false; + } + + public T remove(int index){ + Node node = getNode(index); + Node pre = node.pre; + Node next = node.next; + pre.next = next; + next.pre = pre; + size--; + return node.element; + } + + public void clear(){ + for(Node x = head; x != null; ){ + Node next = x.next; + x.pre = null; + x.next = null; + x.element = null; + } + head = last = null; + size = 0; + } + + public int size(){ + return size; + } + + public boolean isEmpty(){ + return size == 0; + } + + public boolean contains(Object o){ + for(int i = 0; i < size; i++){ + if(Objects.equals(getNode(i).element, o)){ + return true; + } + } + return false; + } + + public Node getNode(int index){ + if(index < 0 || index >size){ + return null; + } + Node node = head; + for(int i = 0; i < index; i++){ + node = node.next; + } + return node; + } + + public T get(int index) { + return getNode(index).element; + } + + public int indexOf(T element){ + Node node = head; + int index = 0; + while(node.next != null){ + node = node.next; + if(Objects.equals(node.element, element)){ + return index; + } + index++; + } + return -1; + } + + private static class Node { + T element; + Node pre; + Node next; + + Node(T element) { + this.element = element; + } + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + T t; + for(int i = 0; i < size; i++) { + t = getNode(i).element; + getNode(i).element = getNode(size-1-i).element; + getNode(size-1-i).element = t; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(size < 2) { + return; + } + int half = size >> 1; + for(int i = 0; i < half; i++) { + remove(i); + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if((i+length)<0 || (i+length)>size) { + return;//抛出异常 + } + for(int n = i - 1; n <= length; n++) { + remove(n); + } + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedListV02 list){ + if(list == null) { + return null; + } + int[] result = new int[list.size()]; + for(int i = 0; i < list.size(); i++) { + if(list.get(i) < size) { + result[i] = (Integer) this.get(i); + } + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedListV02 list){ + if(list == null || list.size() == 0) { + return; + } + for(int i = 0; i < list.size(); i++) { + if(this.contains(list.get(i))) { + this.remove((T) list.get(i)); + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + LinkedListV02 newList = new LinkedListV02<>(); + for(int i = 0; i < size; i++) { + if(!newList.contains(this.get(i))) { + newList.add(this.get(i)); + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(min > max) { + return; + } + if((Integer)head.element > min && (Integer)last.element < max) { + clear(); + } else if ((Integer)head.element > min && (Integer)last.element > max) { + Node temp1 = last; + Node temp2 = head; + while(temp1.pre != null) { + temp1 = temp1.pre; + if(Objects.equals(temp1.element, max)) { + last = temp1; + } else { + temp1.pre = null; + temp1.element = null; + } + temp1.next = null; + } + while(temp2.next != null) { + temp2 = temp2.next; + if(Objects.equals(temp2.element, min)) { + head = temp2; + } else { + temp2.next = null; + temp2.element = null; + } + temp2.pre = null; + } + } + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedListV02 intersection(LinkedListV02 list){ + if(list == null || list.size() == 0) { + return null; + } + LinkedListV02 newList = new LinkedListV02(); + for(int i = 0; i < list.size(); i ++) { + if(this.contains(list.get(i))) { + newList.add(list.get(i)); + } + } + return newList; + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadFileMultiThread.java b/group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadFileMultiThread.java new file mode 100644 index 0000000000..5885ce822c --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadFileMultiThread.java @@ -0,0 +1,88 @@ +package com.bruce.homework0312.mydownload; + +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * Created by Bruce.Jiao on 2017/3/11. + */ +public class DownloadFileMultiThread { + private String path; + private int threadCount; + + public DownloadFileMultiThread(String path, int threadCount){ + this.path = path; + this.threadCount = threadCount; + } + + public void download() throws Exception { + URL url = new URL(path); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(6000); + conn.setRequestMethod("GET"); + //从服务器请求全部资源返回200,请求部分资源返回206 + int code = conn.getResponseCode(); + if(code == 200) { + //返回的文件的长度 + int length = conn.getContentLength(); + //在客户端本地创建一个大小跟服务器端文件大小一样的本地临时文件 + RandomAccessFile raf = new RandomAccessFile("log4j.jar","rw"); + raf.setLength(length); + raf.close(); + int blockSize = length/threadCount; + for(int threadId = 1; threadId < threadCount; threadId++) { + int startIndex = (threadId - 1)*blockSize; + int endIndex = threadId*blockSize - 1; + if(threadId == threadCount) { + endIndex = length; + } + new DownloadThread(path, threadId, startIndex, endIndex); + } + } + } + + public static class DownloadThread extends Thread { + private String path; + private int threadId; + private int startIndex; + private int endIndex; + + public DownloadThread(String path, int threadId, int startIndex, int endIndex) { + super(); + this.path = path; + this.threadId = threadId; + this.startIndex = startIndex; + this.endIndex = endIndex; + } + + @Override + public void run() { + try { + URL url = new URL(path); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(6000); + conn.setRequestMethod("GET"); + //请求服务器下载部分文件,指定文件的位置 + conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); + int code = conn.getResponseCode(); + //已经设置了请求的位置,返回的是当前位置对应的文件的输入流 + InputStream is = conn.getInputStream(); + RandomAccessFile raf = new RandomAccessFile("log4j.jar", "rw"); + //定位文件 + raf.seek(startIndex); + int len = 0; + byte[] buffer = new byte[1024]; + while((len = is.read(buffer)) != -1) { + raf.write(buffer, 0, len); + } + is.close(); + raf.close(); + System.out.println("线程:" + threadId + "下载完毕"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadTest.java b/group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadTest.java new file mode 100644 index 0000000000..22fb46e494 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0312/mydownload/DownloadTest.java @@ -0,0 +1,17 @@ +package com.bruce.homework0312.mydownload; + +import org.junit.Test; + +public class DownloadTest { + + @Test + public void test() { + String path = "http://mirrors.tuna.tsinghua.edu.cn/apache/logging/log4j/2.8.1/apache-log4j-2.8.1-bin.zip"; + DownloadFileMultiThread dfmt = new DownloadFileMultiThread(path, 3); + try { + dfmt.download(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0402/jvm/loader/ClassFileLoader.java b/group15/1510_739253131/src/com/bruce/homework0402/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..0f6d5e60d0 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0402/jvm/loader/ClassFileLoader.java @@ -0,0 +1,61 @@ +package com.bruce.homework0402.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList<>(); + + //TODO 方法需要调试 + public byte[] readBinaryCode(String className) { + InputStream is = null; + try { + className = className.replace(".", "/"); + String path = getClassPath() + "/" + className +".class"; + URL url = new URL(path); + byte[] buff = new byte[1024*2]; + int len = -1; + is = url.openStream(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + while((len = is.read(buff)) != -1) { + outputStream.write(buff, 0, len); + } + return outputStream.toByteArray(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < clzPaths.size(); i++) { + sb.append(clzPaths.get(i)); + if(i != (clzPaths.size()-1)) { + sb.append(";"); + } + } + return sb.toString(); + } +} diff --git a/group15/1510_739253131/src/com/bruce/homework0402/jvm/test/ClassFileloaderTest.java b/group15/1510_739253131/src/com/bruce/homework0402/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..71007b752c --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0402/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,71 @@ +package com.bruce.homework0402.jvm.test; + +import com.bruce.homework0402.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 = "/F:/coding2017/group15/1510_739253131/out/production/1510_739253131"; + 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.bruce.homework0402.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.bruce.homework0402.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) {//添加新节点后,size大于capacity,把最后一个节点去掉,last 指针向前移动一位 + last = last.prev; + last.next = null; + } + } else { + moveToFirst(node); + } + } + } + + private Node exist(int pageNum) { + Node node = first; + while(node != null) { + if (node.pageNum == pageNum) { + return node; + } + node = node.next; + } + return null; + } + + private static class Node { + Node prev; + Node next; + int pageNum; + Node() {} + Node(int pageNum) { + this.pageNum = pageNum; + } + } + + private void moveLastToFirst() { + //将first和last双向链接起来 + last.next = first; + first.prev = last; + //移动first和last的“指针” + first = last; + last = last.prev; + //打断first和last的双向链接 + last.next = null; + first.prev = null; + } + + private void addToFirst(int pageNum) { + Node node = new Node(pageNum); + node.next = first; + node.prev = null; + first.prev = node; + first = node; + size++; + } + + private void moveToFirst(Node node) { + node.prev.next = node.next; + node.next.prev = node.prev; + node.next = first; + node.prev = null; + 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/group15/1510_739253131/src/com/bruce/homework0402/lru/LRUPageFrameTest.java b/group15/1510_739253131/src/com/bruce/homework0402/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..26fa845d46 --- /dev/null +++ b/group15/1510_739253131/src/com/bruce/homework0402/lru/LRUPageFrameTest.java @@ -0,0 +1,37 @@ +package com.bruce.homework0402.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); + System.out.println(frame.toString()); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + System.out.println(frame.toString()); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + System.out.println(frame.toString()); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + System.out.println(frame.toString()); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group15/1511_714512544/.idea/encodings.xml b/group15/1511_714512544/.idea/encodings.xml index cfca28230a..6e94f060a7 100644 --- a/group15/1511_714512544/.idea/encodings.xml +++ b/group15/1511_714512544/.idea/encodings.xml @@ -1,6 +1,7 @@ + \ No newline at end of file diff --git a/group15/1511_714512544/.idea/workspace.xml b/group15/1511_714512544/.idea/workspace.xml index cb4932867a..79ca1863c1 100644 --- a/group15/1511_714512544/.idea/workspace.xml +++ b/group15/1511_714512544/.idea/workspace.xml @@ -1,7 +1,7 @@ - + - + @@ -47,25 +46,19 @@ @@ -75,25 +68,15 @@ true DEFINITION_ORDER - - - - - + @@ -107,8 +90,6 @@ - - @@ -134,8 +115,22 @@ + + + - + + + + @@ -157,7 +152,7 @@ + + - - - - - - - - - - - - - - - - - - - - + + - - + + - - + - - + - - + - - + - - + + - @@ -786,19 +779,19 @@ - - - - - + + + + + - - - - - + + + + + @@ -810,198 +803,105 @@ - - 1487829138626 + + 1488937211416 - 1487829266287 + 1488937445293 - 1487829432867 + 1489156650791 - 1487856987141 + 1489206126088 - 1487857271746 + 1489209258691 - 1487857304368 + 1489211483985 - 1488004359192 + 1489303022487 - - 1488019343082 - - - 1488019461939 - - - 1488157251542 - - - 1488157483941 - - - 1488331339727 - - - 1488372676888 - - - 1488535940734 - - - 1488543482582 - - - 1488544609996 - - - 1488547243625 - - - 1488603987319 - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - @@ -1017,30 +917,28 @@ + - - + + + + + + + + + - + - - - - - - - - - - - + @@ -1079,238 +977,248 @@ - - - - - - - - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - - + + - + - - - + + - + - - + + - - + + - + + + + + + + + - + + + + + - + - - + + - + - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - + - + - - + + @@ -1321,246 +1229,155 @@ - + - - + + - + - - + + - + - - + + - + - - + + - + - + - + - - + + - - - - + + + + + + + - + - - + + - + - - + + - + - - + + + - + - - + + - + - - + + + - + - - + + + - + - - - - - - - - - + + + - + - - + + - - + + + + + - + - - - - - - - - - - - - - - - - - + + + - + - - - + + + + + + - + - - - + + + + + + - - - - - - - - - - - - - No facets are configured - - - - - - - - - - - - - - - 1.8 - - - - - - - - 1511_714512544 - - - - - - - - 1.8 - - - - - - - - - - - - - - \ No newline at end of file diff --git a/group15/1511_714512544/out/production/1511_714512544/com/coderising/array/ArrayUtil.class b/group15/1511_714512544/out/production/1511_714512544/com/coderising/array/ArrayUtil.class index e84a8b4b40a336a676640e060b4cb063c3929131..42fd928c332f1bad0e81786b1c965844635a0608 100644 GIT binary patch delta 752 zcmX|<+iy%^6vfxk`Fdu~C@pG6N2jVat+`O46^FXDj83YeuOuST)}k~LCv*1M-(GvKwf6Tl@i18%imdu5!%rH>eNtp8 z7>)SljAA5KlWta2E%LNRty-%#ty6|*JKz0Ekdby#)udh}wLuZvhMHF1HfmE!4jr~> zBd06qlUF-YgVLO@RD<~~*KwSm>Y=VfoA_@LL%&fHrKAWaYm!gr|HRTVjej8Gy6SS( z&EvQVzL-SE91<5E)38qJh)(OM&Ja&%L>E=kP0nxWxGEacyiSCACh6FTwf~GR!Mi6^R>a<3ZN-;C zx+lj-+I3dza;q3)_h56mP;Oc?Y$AopKI5(M2&1B*87ABf7JJ70k{4v%5$9BJ!(Av$ zax12|73ZOIf$d)cH_b9;xC585@(Kd4LVQ}sbUpB+p9{A^lri@%s9A{LV`c>ob1dvW zMpQt}BY75y4;K4kPX8kik3l>E@f5@Yh-V<4YlmKFw_Y;il}5>pYf)#ZnbPZE!u#I7 bgz7hFc#G-F*zpcl%jkQrgZdDhi(mT-)8k`` delta 699 zcmX|Ec$ft)x^iKUq>=Oy{hN}-mId6NtJIEM?;yt zMEaoI#%CX@2GEtq>m8gAavIX8?rH)&tr5-Xz81(o)|i$xt`#zNeoqu*5{ZBF>qc1% zntW>H@Ybes&Vymr?xtY<3;`@`4-Hw=5gH08+zE;xWG1xc5(z@PUO4iMg5QdpNB)E} zZ;t%E>>{&WV#^QE@=(>NOQEPyPuc4;)IP_>OWh+ju4VHo_?}&bvBregVQrx6H4Qfr zu*EKlx&_Yb4c<0z{r2;VsMGTf#x{)iFm_-V7$0DK#N#Knw@Z&bO%a>bK5BO8erOJ3 eKhj^=)>jN1@$Wlk79~_2v$b!`^~4;+SIz+R?o@yP diff --git a/group15/1511_714512544/out/production/1511_714512544/com/coding/basic/LinkedList$ListIterator.class b/group15/1511_714512544/out/production/1511_714512544/com/coding/basic/LinkedList$ListIterator.class index 4097ca643318b50905b81e3d87a82a79bf07a08f..9a0793e3b3215133de2b3d701c6bb003137a24f1 100644 GIT binary patch delta 47 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 Kte9gJT>k+Z{34G4 delta 1519 zcmZ9MTW=Fr6ouD}FJn8laUhHnJLHB#s2dlR&N%LP{G7f=C1q0@|w3&;kJo zA>QCPIi$AW~4)JjM^@WK;+frq~F2U?Y?-#Igc3Rya5d}g1u*4}&V`FZD`&GWDR z{r$P5A$^h7I*n#j&^}LN8O5|e%~ChV2Rx0ZG?9^~gXZv1hQrB}raVn&l+%o-SxCI!G^>DC-Yey zQ@1(k59Sji$&wZv!j}@|ppd+uh+kR0el>WMTv}Eq^aVL;l*{ zr46d9$>MZSm{xw9iE_DdAVM@x6?KETh0~nk#eWp{)RX_)Qg>>rrF)Qic-zp`fEN%x z`D`MiZRFAq>^LM-K+Ym_0g;OcI}PwM(BFe`OP^R7qa-(_D*uWInpF?aEs7JDM{#^E7DHRADym3X5x=LcS6=j4qcq8zZfzJXyu_>32#x@UDYxN61NEddVh9#7epP zRKdN>b*rI{52RrY@(mswS<@ zNph)B9n&b6TeV1CT{|OnC+J2W5pnMNCT`G{a%C;Gl_<5a%ZYrtE6SshJn*!w-LDOP z&j$m}S?-SwI1m}|ZA0&fiOrL_7?y(OsoF7n$F~+MuaTFna^v;E==RaR)|HNv z-ucgq;)hejpQb)%G)-P+9E^>nnKk5@2)ROELu;D^`98EqHimPEDuwfQ zi`&NhebwL85cKByr%eXFE!9~DW|^L!1Mxh4z3{(G`XauTs0ZP&#N?RbeHOw8zvRNE zk1~DICEzXtcZFg22G@Q|d%n{E!!S%+M|6$3`+@eZ=&*jI06&rR4Fue@v_nYh1Rf6PA@ z=e+;q+_B_g$1@>iAq7<}Liq5#dMfAR%L%pBEWhDM;O`E07pI$bFEc9q5z~5hff}Ps LO>`>9zESRf^@EOZ diff --git "a/group15/1511_714512544/out/production/1511_714512544/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" "b/group15/1511_714512544/out/production/1511_714512544/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" new file mode 100644 index 0000000000..e6a6969727 --- /dev/null +++ "b/group15/1511_714512544/out/production/1511_714512544/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" @@ -0,0 +1,5 @@ + +1. 每个结点的平衡因子就是该结点的左子树的高度减去右子树的高度,平衡二叉树的每个结点的平衡因子的绝对值不会超过2。 +2. 右旋口诀:左子作父,父为右子,右孙变左孙 + 左旋口诀:右子作父,父为左子,左孙变右孙 + diff --git a/group15/1511_714512544/out/production/1511_714512544/test/com/coding/basic/LinkedListTest.class b/group15/1511_714512544/out/production/1511_714512544/test/com/coding/basic/LinkedListTest.class index 2b2fb7b768fcbe5dfa73c58e225d5448b4b06b81..8375422df0fe83e6e4ea3ca15c84d48a9db02675 100644 GIT binary patch literal 6626 zcmcJUd303O9ml^nGm{CE2U$qMCJ-RNgvr9%0!fhsf+h@M2?kliOY#T;m)1=?(+M7 ze!t(n_l4Ilyz(l5`FP%g3f$<%Mh~)ZqX(O?S=P3=_*DKl9Ju?UrppH$om1$!Uua&Otrjv!zD+=WTDF0C1h=GFUwxeyiH0_NWRfQAK!zxXg{a6&%Jr3KQjC1

6jiU?9pAkD9C(W4Bm`gkDNsYMk$hQ|d& zsjNJq;7L5C;AuRgV7Z*CK^80Ukb>)EaXqROG|HkL&nj4nPrC7(9P}x<3)tCA}ci z2N6uSoFd2oE=~tykDJ*Km(2N%9gi~*K(^Z5t%bQeRrWJ7)wHxAr2T3A&4)FE_0Q2G zW-ozs&DL1@#8B7Ax4kpdRF}8WFnNkM(=*A`ttpqggc+N0JrJy}i$>M`ba{z)b6POj z>y}<(J}zB*i7ta0gemax{FFbVL2#&IS?RVGP#cWPhOI9I`gP1c%?}JPT(6E}zT#%r-xZknKw#=g?Vxjmr6{JMCC0iX=G@l0IVi&de1z+Nl%t&dT!=-iNlO>=Q=rDS>pbmqux*uX zm%}v7<8zvpd3+AjG!N~{T~+Zi6oJzyd=VpAA0?1L-kFQ<%050v0{LfAAPsjIaAsfx z>*Hzo1e$*hYZEaIli}2?iA&f^LDqlab>mt$ zmW~-vV4W>+A7_=|XJ3ZEz8XvioA75+gO?i0sbLl^_R*~sDe!08c6%=Yzuva(ecC4B z$1lS+U$)x_5RcEDV^v7Ia0A^S<0XO7Y3?aw`#BUb)QWq(R8lx5fw2jUOJMw&i*F{K zG?!2bhyv$O;9LrvM}hMxZ-F7DhL{@|LrsjL7DkXxcO)Gaw}po+;Z20o$6-yT!^#JA z*fJZ+2`f|Th6JSu6Ef3hDy4z3mcygFfJf_i9{baH09R1f0v^9hdHPC0W*XJmf)-hV z21=vlw$UG0p4>YmqkRs;qZ5bCmn$jNPpPXYwV6^^Q|cOuS<5t9N3kt@x*j+1w+9*GawdUDj@g<#N%3Cx8AYDhivf!+?agk!RYdt=c3D(Z(XH$5KOtsL-8~rJi;s2 zqr7rG#v97xyaPPJqw+}}g->zUc$%llGki~bmO1oX3XG5qL$hGiXTqrOg^_+a^r=IZUWHupf1c7mL+PKT^v_ZH=PCUQl=wvo`VwQ{1;)UOjDatw$iA`| zNSEDY%YNIE-8G=+2bAq}B{1zOg`cJHmnr-e3O`5TU!m~x6!|JIFJI-w=4-q)d>uRR zjTGTsw!hmff7fREyS9ISuj~~r#?tRjqCaj6&(Ae(28?OVsubY0-kPYiYbWg5hrP9| zjdtz4S+izcRbfR@g_S227S0MgaViohYvzu@1*Ru3LtYilyYLEb2*5W<=v%D4#;xIX zzHEG(3ciDd_%5^IdptwGk5>GEC+rVN=|?2GYH>K+ikwx;<1J#;2m-@Ez`GN&1xxG$^QvBH6W|L!PL9;Tv1xiYOZ8nE_RM{TA4XLnVGV!pVWLq?q%lRCXCb+ z#e`NuXk!R%ETN4fwDFiDCSZ}chR`OWQB1;GF`3Xxv0Y5T4lxzoVj510=?1v@rc@i; yQ9Cs^S*f|5FVyRqqz>+fmBy>F(@4^B$hycTmm4?qW~xk9ka+rr*Gi+au;G6dQ0>70 literal 3856 zcmb`KTUQfT7>3^=ArptO%E5DKsYMJ#4dNL*0E#v^fP!K@J0v3xBr`FYAb4)Oyy&^E zUiBAv-CjgnSNj9{5Bv?iX;-gX`|ivzAx6Qn!YuaQvrpgmKHsdBe zy3l7?wxbt^C9Kx$>||^zPbo3amO@+ob8#za%t{EGj*-88;ad^n22v!=bE^wr9v9m@{v)3e&=IGb^;nY-+k_)wz?re#L!rhm)WIOgH-ZkCJlyG zp3zfzW8}JowUKzcRxyL|T@zW*?ON{*X%5(V4zF?dH|^Ld2E<`l3_VQ+L94jB ziFQf?JtgxX%NG$$Mr@I?g#I!x{<^KN;ZnJO@rK|I1Q60Q8N=df-u{}E3tcPAC;DGD z-yQ5(Y<}3W-B}XKHG69rlcKs;VmrU{I6mOBxp>*uK@um7pL(oE16t6CDDQ4zcdfg(XE#i%QEa3A?HmiT-a+SGPdiyl*y;QA zEByHMA3H#{&4BzTc50;P3Z+ z`-{E_`1!Z+EgF)G38F;hu-72%hI0&q$d>{d%fi#j{^w|7s;!xi(%Ob~1*|V%LjfC~ zynIm#QWv3uITEI%dUR6YP73T|2JONgLhoTYfW7?FVjsr%5pZ~!mjageg{M8?gREZ( z*q|G*_BRIXfDh%dcT)P61*Hj_Dv!@*N&^nFJVJrJ6xc_B{SGdXiE#N*$uqVM-n0clQ)d;52(jahB1XVOfgh zEnm9rN!Kc4sVx=Dp6X(GuWDG%6Uzl+xkxORh~+Y|Tp^aL#Bz;TbYhtxkOZ+9RmXDB z$MUC_Eza_?rGWRVckE3vnIe;EGD(q1noKM*v3bZdJR3I==bwY4$nnW9VB+|xlJZg| zUYRQKrBdZk^_a9&kI5XF+$NJdWOA2G?vcrTGI>BI56R>cGWnEDJ|mMyRcF%WGkM|V ziLu-~DSfX0&-b7M3a`u03E>Mu_>vI5B80CA;TuBumJq(<#rc^3R(!ueyx}LrWiKJR QD-)u7sf0L8%QZOi9|gJ4mjD0& diff --git a/group15/1511_714512544/src/com/coderising/array/ArrayUtil.java b/group15/1511_714512544/src/com/coderising/array/ArrayUtil.java index cd48c18e32..a3013ef153 100644 --- a/group15/1511_714512544/src/com/coderising/array/ArrayUtil.java +++ b/group15/1511_714512544/src/com/coderising/array/ArrayUtil.java @@ -12,6 +12,7 @@ public class ArrayUtil { * @return */ public void reverseArray(int[] origin){ + if(origin == null) return ; //边界条件 int len = origin.length; int temp = 0; for (int i = 0; i < len/2; i++) { @@ -30,6 +31,7 @@ public void reverseArray(int[] origin){ */ public int[] removeZero(int[] oldArray){ + if(oldArray == null) return null; //边界条件 int[] temp = new int[oldArray.length]; int index = 0; for (int i : oldArray) { @@ -52,6 +54,10 @@ public int[] removeZero(int[] oldArray){ */ public int[] merge(int[] array1, int[] array2){ + if(array1 == null && array2 == null ) return null; + if(array1 == null) return array2; + if(array2 == null) return array1; + int[] array3 = new int[array1.length+array2.length]; for (int i = 0; i < array1.length; i++) { array3[i] = array1[i]; diff --git a/group15/1511_714512544/src/com/coderising/download/Demo.java b/group15/1511_714512544/src/com/coderising/download/Demo.java new file mode 100644 index 0000000000..72f9d8efc0 --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/Demo.java @@ -0,0 +1,99 @@ +package com.coderising.download; + +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; + +public class Demo { + public static String path = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png"; + public static int threadCount = 3; + public static void main(String[] args) throws Exception{ + //1.连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件 + URL url = new URL(path); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + conn.setConnectTimeout(5000); + conn.setRequestMethod("GET"); + int code = conn.getResponseCode(); + if (code == 200) { + //服务器端返回的数据的长度,实际上就是文件的长度 + int length = conn.getContentLength(); + System.out.println("文件总长度:"+length); + //在客户端本地创建出来一个大小跟服务器端一样大小的临时文件 + RandomAccessFile raf = new RandomAccessFile("d:/1.png", "rwd"); + //指定创建的这个文件的长度 + raf.setLength(length); + raf.close(); + //假设是3个线程去下载资源。 + //平均每一个线程下载的文件大小. + int blockSize = length / threadCount; + for (int threadId = 1; threadId <= threadCount; threadId++) { + //第一个线程下载的开始位置 + int startIndex = (threadId - 1) * blockSize; + int endIndex = threadId * blockSize - 1; + if (threadId == threadCount) {//最后一个线程下载的长度要稍微长一点 + endIndex = length; + } + System.out.println("线程:"+threadId+"下载:---"+startIndex+"--->"+endIndex); + new DownLoadThread(path, threadId, startIndex, endIndex).start(); + } + + }else { + System.out.printf("服务器错误!"); + } + } + + /** + * 下载文件的子线程 每一个线程下载对应位置的文件 + * @author jie + * + */ + public static class DownLoadThread extends Thread{ + private int threadId; + private int startIndex; + private int endIndex; + /** + * @param path 下载文件在服务器上的路径 + * @param threadId 线程Id + * @param startIndex 线程下载的开始位置 + * @param endIndex 线程下载的结束位置 + */ + public DownLoadThread(String path, int threadId, int startIndex, int endIndex) { + super(); + this.threadId = threadId; + this.startIndex = startIndex; + this.endIndex = endIndex; + } + + @Override + public void run() { + try { + URL url = new URL(path); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + conn.setConnectTimeout(5000); + conn.setRequestMethod("GET"); + //重要:请求服务器下载部分文件 指定文件的位置 + conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); + //从服务器请求全部资源返回200 ok如果从服务器请求部分资源 返回 206 ok + int code = conn.getResponseCode(); + System.out.println("code:"+code); + InputStream is = conn.getInputStream();//已经设置了请求的位置,返回的是当前位置对应的文件的输入流 + RandomAccessFile raf = new RandomAccessFile("d:/1.png", "rwd"); + //随机写文件的时候从哪个位置开始写 + raf.seek(startIndex);//定位文件 + + int len = 0; + byte[] buffer = new byte[1024]; + while ((len = is.read(buffer)) != -1) { + raf.write(buffer, 0, len); + } + is.close(); + raf.close(); + System.out.println("线程:"+threadId+"下载完毕"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } +} \ No newline at end of file diff --git a/group15/1511_714512544/src/com/coderising/download/DownloadThread.java b/group15/1511_714512544/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..9173329f7b --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,58 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionImpl; +import com.coderising.download.impl.ConnectionManagerImpl; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.net.URL; + +public class DownloadThread extends Thread{ + int startPos; + int endPos; + String url; + String savePath; + DownloadListener listener; + private static int count = 0; + private Object lock = new Object(); //对象锁 + + public DownloadThread(String url, String savePath, DownloadListener listener, int startPos, int endPos){ + this.startPos = startPos; + this.endPos = endPos; + this.url = url; + this.savePath = savePath; + this.listener = listener; + } + public void run(){ + RandomAccessFile raf = null; + //实现 + try { + Connection conn = new ConnectionManagerImpl().open(url); + raf = new RandomAccessFile(savePath,"rwd"); + + byte[] data= conn.read(startPos,endPos); + + raf.seek(startPos); + raf.write(data); + synchronized (lock){ //加对象锁 + count ++; + if(count == 3){ + listener.notifyFinished(); + } + } + + } catch (Exception e) { + throw new RuntimeException("读取错误"); + }finally { + try { + if(raf != null){ + raf.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/group15/1511_714512544/src/com/coderising/download/FileDownloader.java b/group15/1511_714512544/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c620180530 --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,81 @@ +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; + +import java.io.RandomAccessFile; + +/** + * 文件下载器 + */ +public class FileDownloader { + String url; //下载路径 + String savePath = "d:/1.png"; //保存路径 + 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; + RandomAccessFile raf = null; + try { + cm = new ConnectionManagerImpl(); + conn = cm.open(this.url); + int length = conn.getContentLength(); + + raf = new RandomAccessFile(savePath,"rwd"); + if(raf.length() == 0){ + raf.setLength(length); + } + raf.close(); + + for (int i = 0; i <= 2; i++) { + int startPos = i*length/3; + int endPos = length*(i+1)/3-1; + if(i == 2) { + endPos = length-1; + } + new DownloadThread(url, savePath,listener ,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/group15/1511_714512544/src/com/coderising/download/FileDownloaderTest.java b/group15/1511_714512544/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..11d8087369 --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,58 @@ +package com.coderising.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; //是否下载完 + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "https://www.baidu.com/img/bd_logo1.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("Down!!!"); + + + + } + +} diff --git a/group15/1511_714512544/src/com/coderising/download/api/Connection.java b/group15/1511_714512544/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..d2c1b08dba --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/api/Connection.java @@ -0,0 +1,24 @@ +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/group15/1511_714512544/src/com/coderising/download/api/ConnectionException.java b/group15/1511_714512544/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group15/1511_714512544/src/com/coderising/download/api/ConnectionManager.java b/group15/1511_714512544/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group15/1511_714512544/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/group15/1511_714512544/src/com/coderising/download/api/DownloadListener.java b/group15/1511_714512544/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group15/1511_714512544/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/group15/1511_714512544/src/com/coderising/download/impl/ConnectionImpl.java b/group15/1511_714512544/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..d655844039 --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,68 @@ +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 HttpURLConnection connection; + + public ConnectionImpl(HttpURLConnection connection) { + this.connection = connection; + } + + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + @Override + + public byte[] read(int startPos, int endPos) throws IOException { + byte[] buffer = new byte[endPos-startPos+1]; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + connection.setRequestProperty("Range", "bytes="+startPos+"-"+endPos); + int res = connection.getResponseCode(); + if(res == 206){ //下载部分内容请求成功 + InputStream in = connection.getInputStream(); + + int len = 0; + byte[] b = new byte[1024]; + while ((len = in.read(b)) != -1) { + bos.write(b, 0, len); + } + buffer = bos.toByteArray(); + } + + return buffer; + } + /** + * 得到数据内容的长度 + * @return + */ + @Override + public int getContentLength() { + return connection.getContentLength(); + } + /** + * 关闭连接 + */ + @Override + public void close() { + InputStream in; + try { + in = connection.getInputStream(); + if(in != null){ + in.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/group15/1511_714512544/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group15/1511_714512544/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..55d27dc156 --- /dev/null +++ b/group15/1511_714512544/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,38 @@ +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.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + @Override + public Connection open(String url) throws ConnectionException { + try { + URL u = new URL(url); + HttpURLConnection conn = (HttpURLConnection) u.openConnection(); + conn.setConnectTimeout(5000); + conn.setRequestMethod("GET"); + int code = conn.getResponseCode(); + if(code == 200){ + return new ConnectionImpl(conn); + }else { + throw new RuntimeException("打开连接失败"); + } + } catch (MalformedURLException e) { + throw new RuntimeException("url非法"); + } catch (IOException e) { + throw new RuntimeException("IO异常"); + } + } + +} diff --git a/group15/1511_714512544/src/com/coding/basic/LinkedList.java b/group15/1511_714512544/src/com/coding/basic/LinkedList.java index e806c0e6a2..423a56e2a8 100644 --- a/group15/1511_714512544/src/com/coding/basic/LinkedList.java +++ b/group15/1511_714512544/src/com/coding/basic/LinkedList.java @@ -1,6 +1,7 @@ package com.coding.basic; import java.util.NoSuchElementException; +import java.util.Objects; public class LinkedList implements List { private Node head; //首节点 @@ -51,6 +52,7 @@ public Object get(int index){ //取出指定节点处的元素,从0开始 return temp.data; } + public Object remove(int index){ //删除指定索引处的节点 if(index > size -1 || index < 0) throw new RuntimeException("IndexOutOfBounds"); if(index == 0) { //第一个元素或只有一个元素 @@ -154,4 +156,214 @@ public Node(Object data, Node next) { this.next = next; } } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + 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(size() == 0 || size() == 1) return; + + int half = size()/2; //一半数目 + int sum = 0; //已移除总个数 + while(sum != half){ + head = head.next; + sum ++; + size --; + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(length < 0 ) throw new RuntimeException("长度非法"); + if(i < 0 || i >= size() || (i+length >size())) throw new RuntimeException("索引越界"); + + if(i == 0){ + int sum = 0; + while(sum != length){ + head = head.next; + sum ++; + size --; + } + return; + } + Node pre = findNode(i-1); //前一节点 + Node next = findNode(i+length); //后一节点 + pre.next = next; + size -= length; + } + //查找某个位置的Node + private Node findNode(int i){ + if(i < 0 ||i > size()) throw new RuntimeException("索引越界"); + if(i == size() ) return null; + int index = 0; + Node temp = head; + while(index != i){ + temp = temp.next; + index ++; + } + return temp; + } + + /** + * 假定当前链表和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 sum = list.size(); + int[] arr = new int[sum]; + for (int i = 0; i < sum; i++) { + Integer index = (Integer) list.get(i); + Node temp = findNode(index); + if(temp == null){ + throw new RuntimeException("索引越界"); + } + arr[i] = (Integer) temp.data; + } + return arr; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + public void subtract(LinkedList list){ + for (int i = 0; i < list.size; i++) { + int index = indexOf(list.get(i)); + if(index < 0) continue; //没找到相关节点 + if(index == 0){ + head = head.next; + size --; + }else { + Node pre = findNode(index-1); + Node next = findNode(index+1); + pre.next = next; + size --; + } + } + } + //索引对象,返回索引值 + private int indexOf(Object o){//返回索引 + for (int i = 0; i < size(); i++) { + if(Objects.equals(o, get(i))){ //判断两个Object对象是否相等 + return i; + } + } + return -1; + } + + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(size() == 0 || size() == 1) return; + Node current = head; + + while(current.next != null){ + if(Objects.equals(current.data, current.next.data)){ + current.next = current.next.next; + size --; + }else { + current = current.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(size() == 0) return; + if(((Integer)get(0)) >= max ) return; + if( ((Integer)get(size()-1)) <= min ) return; + + if(((Integer)get(0)) <= min && ((Integer)get(size()-1)) < max && ((Integer)get(size()-1)) > min){ + for (int i = 1; i < size(); i++) { + if(((Integer)get(i)) >min) {findNode(i-1).next = null;size = i;return;} + } + }else if(((Integer)get(0)) > min && ((Integer)get(0)) < max && ((Integer)get(size()-1)) >= max){ + for (int i = 0; i < size(); i++) { + if(((Integer)get(i)) >= max){head = findNode(i);size -= 4;return;} + } + }else if(((Integer)get(0)) <= min && ((Integer)get(size()-1)) >= max){ + Node t1=null, t2 =null; + int index1=0, index2=0; + for (int i = 1; i < size(); i++) { + if(((Integer)get(i)) > min){index1 = i;t1 = findNode(i-1);break;} + } + for (int i = 1; i < size(); i++) { + if(((Integer)get(i)) >= max){index2 = i;t2 = findNode(i);break;} + } + t1.next = t2; + size -= (index2-index1); + }else { + head = null; + size = 0; + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + int[] arr1 = new int[this.size()]; + int[] arr2 = new int[list.size()]; + + for (int i = 0; i < this.size(); i++) { + Integer num = (Integer) this.get(i); + arr1[i] = num; + } + for (int i = 0; i < list.size(); i++) { + Integer num = (Integer) list.get(i); + arr2[i] = num; + } + LinkedList l = new LinkedList(); + for (int i = 0; i < arr1.length; i++) { + for (int j = 0; j < arr2.length; j++) { + if(arr1[i] == arr2[j]){ + l.add(arr1[i]); + break; + } + } + } + return l; + } + + } diff --git a/group15/1511_714512544/src/com/coding/basic/List.java b/group15/1511_714512544/src/com/coding/basic/List.java index 4cc4f6fe5b..878c96ebd5 100644 --- a/group15/1511_714512544/src/com/coding/basic/List.java +++ b/group15/1511_714512544/src/com/coding/basic/List.java @@ -13,4 +13,7 @@ public interface List { Object remove(int index); int size(); + + + } diff --git "a/group15/1511_714512544/src/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" "b/group15/1511_714512544/src/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" new file mode 100644 index 0000000000..e6a6969727 --- /dev/null +++ "b/group15/1511_714512544/src/com/coding/basic/\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221AVL.md" @@ -0,0 +1,5 @@ + +1. 每个结点的平衡因子就是该结点的左子树的高度减去右子树的高度,平衡二叉树的每个结点的平衡因子的绝对值不会超过2。 +2. 右旋口诀:左子作父,父为右子,右孙变左孙 + 左旋口诀:右子作父,父为左子,左孙变右孙 + diff --git a/group15/1511_714512544/src/test/com/coding/basic/LinkedListTest.java b/group15/1511_714512544/src/test/com/coding/basic/LinkedListTest.java index e5a2617247..0df3ba4a00 100644 --- a/group15/1511_714512544/src/test/com/coding/basic/LinkedListTest.java +++ b/group15/1511_714512544/src/test/com/coding/basic/LinkedListTest.java @@ -4,6 +4,8 @@ import com.coding.basic.LinkedList; import org.junit.Test; +import java.util.Arrays; + import static org.junit.Assert.*; /** @@ -146,4 +148,147 @@ public void iterator() throws Exception { } } + @Test + public void reverse(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + list.add(6); + list.reverse(); + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } + + @Test + public void removeFirstHalf(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(4); + list.add(5); + list.add(6); + list.removeFirstHalf(); + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } + + @Test + public void removeByLength(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(4); + list.add(5); + list.add(6); + list.remove(1,2); + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } + + @Test + public void getElements(){ + LinkedList list = new LinkedList(); + 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 index = new LinkedList(); + index.add(1); + index.add(3); + index.add(4); + index.add(6); + int[] arr = list.getElements(index); + System.out.println(Arrays.toString(arr)); + } + + @Test + public void subtract(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(4); + list.add(5); + list.add(6); + LinkedList l2 = new LinkedList(); + l2.add(1); + l2.add(3); + l2.add(4); + l2.add(6); + list.subtract(l2); + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } + + @Test + public void removeDuplicateValues(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(2); + list.add(4); + list.add(5); + list.add(5); + list.add(6); + list.add(8); + list.add(10); + list.removeDuplicateValues(); + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } + + @Test + public void removeRange(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(2); + list.add(4); + list.add(5); + list.add(5); + list.add(6); + list.add(8); + list.add(10); + list.removeRange(3,9); + Iterator iterator = list.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } + + @Test + public void intersection(){ + LinkedList list = new LinkedList(); + list.add(1); + list.add(2); + list.add(4); + list.add(5); + list.add(6); + LinkedList l2 = new LinkedList(); + l2.add(1); + l2.add(3); + l2.add(4); + l2.add(6); + LinkedList l3 = list.intersection(l2); + Iterator iterator = l3.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + " "); + } + } } \ No newline at end of file diff --git "a/group15/1511_714512544/\346\226\207\347\253\240\345\234\260\345\235\200.md" "b/group15/1511_714512544/\346\226\207\347\253\240\345\234\260\345\235\200.md" index 3a34a9a3fb..00bbadef42 100644 --- "a/group15/1511_714512544/\346\226\207\347\253\240\345\234\260\345\235\200.md" +++ "b/group15/1511_714512544/\346\226\207\347\253\240\345\234\260\345\235\200.md" @@ -1,3 +1,5 @@ (1)介绍CPU,内存,硬盘,指令以及他们之间的关系的文章地址:http://www.jianshu.com/p/f86ca5072c5d (2)程序的机器及表示: http://www.jianshu.com/p/1eed6fe682cd + +(3)测试驱动开发 http://www.jianshu.com/p/db21bbd6d370 diff --git a/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/loader/ClassFileLoader.java b/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..1ef6855a58 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,54 @@ +package jvm_LRU_170402.coderising.jvm.loader; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + byte[] result = null; + className = className.replace('.', '\\'); + String path = clzPaths.get(0)+"\\"+className+".class"; + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(path, "r"); + int length = (int) raf.length(); + result = new byte[length]; + raf.read(result); + + } catch (IOException e) { + e.printStackTrace(); + }finally{ + if(raf != null){ + try{ + raf.close(); + }catch(IOException e){ + e.printStackTrace(); + } + } + } + return result; + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < clzPaths.size(); i++) { + if(i==clzPaths.size()-1){ + sb.append(clzPaths.get(i)); + break; + } + sb.append(clzPaths.get(i)); + sb.append(";"); + } + return sb.toString(); + } +} diff --git a/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/test/ClassFileloaderTest.java b/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..471308083c --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,89 @@ +package jvm_LRU_170402.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import jvm_LRU_170402.coderising.jvm.loader.ClassFileLoader; + + +public class ClassFileloaderTest { + + + static String path1 = "d:\\HomeWork\\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 = "task0402.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1066, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "task0402.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 0) { + setFirst(newNode); + capacity--; + } else { + setFirst(newNode); + popNode(last.prev); + } + + } + + private void popNode(Node target) { + target.prev.next = target.next; + target.next.prev = target.prev; + } + + private void setFirst(Node target) { + target.prev = first; + target.next = first.next; + first.next.prev = target; + first.next = target; + } + + public Node findNode(int pageNum) { + Node node = first; + while (node.next != last) { + node = node.next; + if (pageNum == node.pageNum) { + return node; + } + } + return null; + } + + public String toString() { + StringBuilder buffer = new StringBuilder(); + Node node = first.next; + while (node != last) { + buffer.append(node.pageNum); + + node = node.next; + if (node != last) { + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coding/basic/linklist/LRUPageFrameTest.java b/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..639a5ff656 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/jvm_LRU_170402/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package jvm_LRU_170402.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/group15/1513_121469918/HomeWork01/src/coding/ArrayList.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/ArrayList.java similarity index 71% rename from group15/1513_121469918/HomeWork01/src/coding/ArrayList.java rename to group15/1513_121469918/HomeWork/src/task0228/coding/basic/ArrayList.java index f85c800084..5d38553f43 100644 --- a/group15/1513_121469918/HomeWork01/src/coding/ArrayList.java +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/ArrayList.java @@ -1,4 +1,4 @@ -package coding; +package task0228.coding.basic; import java.util.NoSuchElementException; @@ -10,11 +10,11 @@ public class ArrayList implements List { public void add(Object o) { int len = size + 1; - // жlistijǷ + if (len > elementData.length) { - // + Object[] newElemDate = new Object[elementData.length + 1]; - // ƾԪص + System.arraycopy(elementData, 0, newElemDate, 0, elementData.length); elementData = newElemDate; } @@ -23,20 +23,20 @@ public void add(Object o) { } public void add(int index, Object o) { - // ǷԽ + if (index < 0 || index > size) { throw new IndexOutOfBoundsException("index:" + index + "size:" + size); } - // Ԫصĩβֱӵadd + if (index == size) { add(o); } else { - // + Object[] newElemData = new Object[elementData.length + 1]; - // indexǰԪص + System.arraycopy(elementData, 0, newElemData, 0, index); newElemData[index] = o; - // index ԺԪص + System.arraycopy(elementData, index, newElemData, index + 1, size - index); elementData = newElemData; @@ -56,16 +56,16 @@ public Object remove(int index) { throw new IndexOutOfBoundsException("index:" + index + "size:" + size); } Object removeElement = elementData[index]; - //һԪصֵҪ + if(index != (size-1)){ - // + Object[] newElemData = new Object[elementData.length]; - // indexǰԪص + System.arraycopy(elementData, 0, newElemData, 0, index); - // index ԺԪص + System.arraycopy(elementData, index+1, newElemData, index, size - index -1); } - //һԪصֱֵӼlist + size--; return removeElement; } @@ -75,44 +75,37 @@ public int size() { } public Iterator iterator() { - return new MyIterator(this); + return new MyIterator(); } private class MyIterator implements Iterator { - private int poi = -1; - private ArrayList array = null; + private int cursor = 0; + - private MyIterator(ArrayList array) { - this.array = array; - } + private MyIterator() {} @Override public boolean hasNext() { - return (poi + 1) < array.size; + return cursor < size; } @Override public Object next() { - // TODO Auto-generated method stub - poi++; - if (poi >= array.size) { - poi--; + // TODO Auto-generated method stub + if (cursor >= size) { throw new IndexOutOfBoundsException(); } - - return array.get(poi); + return get(cursor++); } @Override public Object remove() { // TODO Auto-generated method stub - if (poi < 0) { + if (cursor <= 0) { throw new NoSuchElementException(); } - Object val = array.remove(poi); - poi--; + Object val = ArrayList.this.remove(--cursor); return val; } - } } diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/BinaryTreeNode.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/BinaryTreeNode.java similarity index 96% rename from group15/1513_121469918/HomeWork20170305/src/com/coding/basic/BinaryTreeNode.java rename to group15/1513_121469918/HomeWork/src/task0228/coding/basic/BinaryTreeNode.java index b3a1ee65b6..e26c68aa6c 100644 --- a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/BinaryTreeNode.java +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package com.coding.basic; +package task0228.coding.basic; public class BinaryTreeNode { private Object data; diff --git a/group15/1513_121469918/HomeWork01/src/coding/Iterator.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/Iterator.java similarity index 77% rename from group15/1513_121469918/HomeWork01/src/coding/Iterator.java rename to group15/1513_121469918/HomeWork/src/task0228/coding/basic/Iterator.java index 26ca2a672a..a42b0148cb 100644 --- a/group15/1513_121469918/HomeWork01/src/coding/Iterator.java +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/Iterator.java @@ -1,4 +1,4 @@ -package coding; +package task0228.coding.basic; public interface Iterator { public boolean hasNext(); diff --git a/group15/1513_121469918/HomeWork01/src/coding/LinkedList.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/LinkedList.java similarity index 99% rename from group15/1513_121469918/HomeWork01/src/coding/LinkedList.java rename to group15/1513_121469918/HomeWork/src/task0228/coding/basic/LinkedList.java index 5d15f141f7..226351337c 100644 --- a/group15/1513_121469918/HomeWork01/src/coding/LinkedList.java +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/LinkedList.java @@ -1,4 +1,4 @@ -package coding; +package task0228.coding.basic; import java.util.NoSuchElementException; diff --git a/group15/1513_121469918/HomeWork/src/task0228/coding/basic/List.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/List.java new file mode 100644 index 0000000000..2b6d70155f --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/List.java @@ -0,0 +1,9 @@ +package task0228.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/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Queue.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/Queue.java similarity index 94% rename from group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Queue.java rename to group15/1513_121469918/HomeWork/src/task0228/coding/basic/Queue.java index ea25224bd2..87a19d952f 100644 --- a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Queue.java +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/Queue.java @@ -1,4 +1,4 @@ -package com.coding.basic; +package task0228.coding.basic; import java.util.NoSuchElementException; diff --git a/group15/1513_121469918/HomeWork01/src/coding/Stack.java b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/Stack.java similarity index 95% rename from group15/1513_121469918/HomeWork01/src/coding/Stack.java rename to group15/1513_121469918/HomeWork/src/task0228/coding/basic/Stack.java index 742a6c4e40..504993e9a0 100644 --- a/group15/1513_121469918/HomeWork01/src/coding/Stack.java +++ b/group15/1513_121469918/HomeWork/src/task0228/coding/basic/Stack.java @@ -1,4 +1,4 @@ -package coding; +package task0228.coding.basic; import java.util.NoSuchElementException; diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coderising/array/ArrayUtil.java b/group15/1513_121469918/HomeWork/src/task0305/coding/basic/array/ArrayUtil.java similarity index 96% rename from group15/1513_121469918/HomeWork20170305/src/com/coderising/array/ArrayUtil.java rename to group15/1513_121469918/HomeWork/src/task0305/coding/basic/array/ArrayUtil.java index 985ca47709..ad2eda4e84 100644 --- a/group15/1513_121469918/HomeWork20170305/src/com/coderising/array/ArrayUtil.java +++ b/group15/1513_121469918/HomeWork/src/task0305/coding/basic/array/ArrayUtil.java @@ -1,10 +1,12 @@ -package com.coderising.array; +package task0305.coding.basic.array; import java.util.Arrays; import java.util.TreeSet; -import com.coding.basic.ArrayList; -import com.coding.basic.Iterator; + +import task0228.coding.basic.ArrayList; +import task0228.coding.basic.Iterator; + public class ArrayUtil { @@ -16,6 +18,9 @@ public class ArrayUtil { * @return */ public void reverseArray(int[] origin) { + if(origin == null){ + return ; + } int len = origin.length; for (int i = 0; i < len / 2; i++) { int temp = origin[i]; @@ -180,10 +185,9 @@ public int[] fibonacci(int max) { */ public int[] getPrimes(int max) { - if (max <= 1) { + if (max < 3) { return new int[0]; } else { - // 创建临时数组 int[] temp = new int[max]; int count = 0; // 从零开始遍历到max,如果有是素数就加入临时数组。 @@ -266,6 +270,12 @@ boolean isPerfectNumber(int x) { * @return */ public String join(int[] array, String seperator) { + if(array == null){ + return null; + } + if(array.length ==0){ + return ""; + } StringBuffer sb = new StringBuffer(); for (int i = 0; i < array.length; i++) { if(i == array.length-1){ diff --git a/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/LoginAction.java b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..613ffad09a --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package task0305.conderising.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/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/Struts.java b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/Struts.java similarity index 94% rename from group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/Struts.java rename to group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/Struts.java index a0dd465d25..d522866c92 100644 --- a/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/Struts.java +++ b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/Struts.java @@ -1,4 +1,4 @@ -package com.coderising.litestruts; +package task0305.conderising.litestruts; import java.io.File; import java.lang.reflect.Constructor; @@ -47,7 +47,7 @@ public static View runAction(String actionName, Map parameters) { Element loginName = (Element)doc.selectSingleNode("//action[1]"); Element logoutName = (Element)doc.selectSingleNode("//action[2]"); //判断action的name属性内容 - if(actionName.equals(loginName.attributeValue("name"))){ + if(actionName !=null && actionName.equals(loginName.attributeValue("name"))){ //传入的actionName内容为login则进行login操作 //获取class路径 @@ -101,7 +101,7 @@ public static View runAction(String actionName, Map parameters) { } return view; - }else if(actionName.equals(logoutName.attributeValue("name"))){ + }else if(actionName !=null && actionName.equals(logoutName.attributeValue("name"))){ //actionName是logout则进行logout操作 } diff --git a/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/StrutsTest.java b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b21a3b5f9a --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/StrutsTest.java @@ -0,0 +1,44 @@ +package task0305.conderising.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/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/View.java b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/View.java new file mode 100644 index 0000000000..0afc6e5caa --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0305/conderising/litestruts/View.java @@ -0,0 +1,23 @@ +package task0305.conderising.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/group15/1513_121469918/HomeWork/src/task0312/coderising/download/DownloadThread.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..2f102293cc --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/DownloadThread.java @@ -0,0 +1,59 @@ +package task0312.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import task0312.coderising.download.api.Connection; +import task0312.coderising.download.api.DownloadListener; +import task0312.coderising.download.impl.ConnectionManagerImpl; + + + +public class DownloadThread extends Thread { + private static int finishCount =0; + String url; + String localPath; + int startPos; + int endPos; + private Object lock = new Object(); + DownloadListener listener; + + public DownloadThread(String url,String localPath,int startPos, int endPos, + DownloadListener listener) { + this.url =url; + this.startPos = startPos; + this.endPos = endPos; + this.localPath = localPath; + this.listener =listener; + } + public void run() { + RandomAccessFile ras = null; + Connection conn= null; + try { + ConnectionManagerImpl cm = new ConnectionManagerImpl(); + conn = cm.open(url); + byte[] download = conn.read(startPos, endPos); + ras = new RandomAccessFile(localPath, "rwd"); + ras.seek(startPos); + ras.write(download); + synchronized(lock){ + finishCount++; + if(finishCount == 6){ + listener.notifyFinished(); + } + } + }catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }finally { + if(ras!=null){ + try { + ras.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloader.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..b3509c9642 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloader.java @@ -0,0 +1,80 @@ +package task0312.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import task0312.coderising.download.api.Connection; +import task0312.coderising.download.api.ConnectionManager; +import task0312.coderising.download.api.DownloadListener; +import task0312.coderising.download.impl.ConnectionManagerImpl; + + +public class FileDownloader { + Thread[] threadList = new Thread[6]; + String url; + DownloadListener listener; + ConnectionManager cm; + + public FileDownloader(String _url) { + this.url = _url; + } + + public void execute() { + RandomAccessFile raf = null; + try { + // 打开连接获取长度 + ConnectionManagerImpl cm = new ConnectionManagerImpl(); + Connection conn = cm.open(url); + int length = conn.getContentLength(); + + // 创建本地接收文件 + String localPath = url.substring(url.lastIndexOf('/') + 1); + raf = new RandomAccessFile(localPath, "rwd"); + raf.setLength(length); + raf.close(); + + int blockSize = length / threadList.length;// 每个线程下载的大小 + for (int threadNum = 0; threadNum < threadList.length; threadNum++) { + // 定义每个线程开始位置 + int threadStart = threadNum * blockSize; + // 定义每个线程结束位置 + int threadEnd = (threadNum + 1) * blockSize - 1; + // 定义最后线程结束位置为总长度-1 + if (threadNum == threadList.length - 1) { + threadEnd = length - 1; + } + String threadID = "Thread-" + (threadNum + 1); + threadList[threadNum] = new DownloadThread(url, localPath, threadStart, threadEnd, listener); + threadList[threadNum].start(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (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 setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return this.listener; + } + +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloaderTest.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..546bd89efe --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/FileDownloaderTest.java @@ -0,0 +1,62 @@ +package task0312.coderising.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import task0312.coderising.download.api.ConnectionManager; +import task0312.coderising.download.api.DownloadListener; +import task0312.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://img.ivsky.com/img/tupian/pre/201612/12/qingrenjie_meigui_liwu-004.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 { + //休眠5秒 + System.out.println("还没有下载完成,休眠五秒"); + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/Connection.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/Connection.java new file mode 100644 index 0000000000..43637a27a0 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package task0312.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/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionException.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..f5e373fdf1 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionException.java @@ -0,0 +1,7 @@ +package task0312.coderising.download.api; + +public class ConnectionException extends Exception { + public ConnectionException(String msg){ + super(msg); + } +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionManager.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1a3baecbc1 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package task0312.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/DownloadListener.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..60f26019d4 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package task0312.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionImpl.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..78085252d7 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,50 @@ +package task0312.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +import task0312.coderising.download.api.Connection; + + + +public class ConnectionImpl implements Connection { + HttpURLConnection urlConnect; + public ConnectionImpl(HttpURLConnection urlConnect) { + this.urlConnect = urlConnect; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + byte[] result = new byte[endPos-startPos+1]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // 设置发出请求,指定下载部分 + urlConnect.setRequestProperty("Range", "bytes="+startPos+"-"+endPos); + int code = urlConnect.getResponseCode(); + if(code == 206){ + InputStream is = urlConnect.getInputStream(); + byte[] bys = new byte[1024]; + int len = 0; + while ((len = is.read(bys)) != -1) { + baos.write(bys, 0, len); + } + + result = baos.toByteArray(); + is.close(); + } + return result; + } + + @Override + public int getContentLength() { + return urlConnect.getContentLength(); + } + + @Override + public void close() { + + } + +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionManagerImpl.java b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..a4a38bd93a --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,33 @@ +package task0312.coderising.download.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import task0312.coderising.download.api.Connection; +import task0312.coderising.download.api.ConnectionManager; + + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) { + URL target; + Connection conn = null; + try { + target = new URL(url); + HttpURLConnection httpUrl = (HttpURLConnection) target.openConnection(); + httpUrl.setConnectTimeout(5000); + conn = new ConnectionImpl(httpUrl); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return conn; + } + +} diff --git a/group15/1513_121469918/HomeWork/src/task0312/coding/basic/linkedlist/LinkedList.java b/group15/1513_121469918/HomeWork/src/task0312/coding/basic/linkedlist/LinkedList.java new file mode 100644 index 0000000000..e7f8a75312 --- /dev/null +++ b/group15/1513_121469918/HomeWork/src/task0312/coding/basic/linkedlist/LinkedList.java @@ -0,0 +1,413 @@ +package task0312.coding.basic.linkedlist; + +import java.util.Arrays; +import java.util.NoSuchElementException; + +import javax.management.RuntimeErrorException; + +import task0228.coding.basic.Iterator; +import task0228.coding.basic.List; + + + +public class LinkedList implements List { + private Node head; + private int size; + + public void add(Object o) { + // 判断头是否有数据 + if (head == null) { + head = new Node(o, null); + } else { + Node newNode = head; + while (newNode.next != null) { + newNode = newNode.next; + } + newNode.next = new Node(o, null); + } + size++; + } + + public void add(int index, Object o) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("index:" + index + "size:" + size); + } + Node node = head; + if (index != 0) { + // 不是第一个索引值就找到索引值的前面一个节点 + for (int i = 1; i < index; i++) { + node = node.next; + } + Node newNode = new Node(o, node.next); + node.next = newNode; + size++; + } else { + // 第一个索引值就将头节点指向它 + Node newNode = new Node(o, head); + head = newNode; + size++; + } + } + + public Object get(int index) { + indexCheck(index); + Node node = head; + for (int i = 1; i <= index; i++) { + node = node.next; + } + return node.data; + } + + public Node getNode(int index) { + indexCheck(index); + Node node = head; + int i = 0; + while (i++ < index) { + node = node.next; + } + return node; + } + + public Object remove(int index) { + indexCheck(index); + Node node = head; + Node removeNode; + if (index == 0) { + // 删除第一个节点就把头节点指向原本的第二个节点 + removeNode = head; + head = head.next; + } else { + // 找到索引值的前一个节点 + for (int i = 1; i < index; i++) { + node = node.next; + } + removeNode = node.next; + // 前一个节点指针,指向被删除节点所指向的节点 + node.next = removeNode.next; + } + size--; + return removeNode.data; + } + + public int size() { + return size; + } + + public void addFirst(Object o) { + Node newNode = new Node(o, head.next); + head.next = newNode; + size++; + } + + public void addLast(Object o) { + add(o); + } + + public Object removeFirst() { + // 没有元素就抛异常 + if (size <= 0) { + throw new IndexOutOfBoundsException("size:" + size); + } + Object val = head.data; + head = head.next; + size--; + return val; + } + + public Object removeLast() { + if (size <= 0) { + throw new IndexOutOfBoundsException("size:" + size); + } + Node node = head; + while (node.next != null) { + node = node.next; + } + Object val = node.data; + node = null; + size--; + return val; + } + + public Iterator iterator() { + return new MyIterator(this); + } + + private class MyIterator implements Iterator { + private int poi = -1; + private LinkedList list; + + private MyIterator(LinkedList list) { + this.list = list; + } + + @Override + public boolean hasNext() { + // TODO Auto-generated method stub + return (poi + 1) < list.size; + } + + @Override + public Object next() { + // TODO Auto-generated method stub + poi++; + if (poi >= list.size) { + poi--; + throw new IndexOutOfBoundsException(); + } + + return list.get(poi); + } + + @Override + public Object remove() { + // TODO Auto-generated method stub + if (poi < 0) { + throw new NoSuchElementException(); + } + Object val = list.removeLast(); + poi--; + return val; + } + } + + private void indexCheck(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("index:" + index + "size:" + size); + } + } + + private static class Node { + Object data; + Node next; + + Node(Object data, Node next) { + this.data = data; + this.next = next; + } + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (size == 0) { + return; + } + Node node = head; + Node node2 = new Node(head.data, null); + while (node.next != null) { + node = node.next; + node2 = new Node(node.data, node2); + } + head = node2; + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 + * + */ + public void removeFirstHalf() { + if (size == 0) { + return; + } + int i = size() / 2; + Node node = getNode(i); + head = node; + size -= i; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + indexCheck(i); + if (size == 0 || length <= 0) { + return; + } + if (length >= size) { + if (i == 0) { + head = null; + size = 0; + } else if (i == 1) { + head.next = null; + size = 1; + } else { + Node node = getNode(i - 1); + node.next = null; + size = i; + } + } else { + // lenth>0 &length101->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[] result = new int[list.size()]; + Node node = head; + int len = 0; + int count = 0; + for (int i = 0; i < list.size(); i++) { + int index = (int) list.get(i); + if(index<0 || index>=size()){ + throw new NullPointerException("index:"+index); + } + while (count < index) { + node = node.next; + count++; + } + result[i] =(int)node.data; + len++; + + } + result = Arrays.copyOf(result, len); + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + for (int i = 0; i < size(); i++) { + for (int j = 0; j < list.size(); j++) { + if (get(i).equals(list.get(j))) { + remove(i--); + } + + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (size == 0 || size == 1) { + return; + } + Node node = head; + while (node.next != null) { + if (node.data == node.next.data) { + node.next = node.next.next; + size--; + } else { + node = node.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + if (size == 0 || min >= max) { + return; + } + Node node = head; + int nodeValue = ((Integer) node.data).intValue(); + // 头开始元素值大于min + while (nodeValue > min && nodeValue < max) { + node = node.next; + size--; + if (node == null) { + head = null; + size = 0; + return; + } + nodeValue = ((Integer) node.data).intValue(); + } + head = node;// 当元素值大于等于max就跳出循环赋值给head + // 头开始元素值小于min + if (nodeValue < min) { + while (nodeValue < min) {// 遍历直到元素值大于min + node = node.next; + if (node.next == null) {// 最后元素值都比min小 + return; + } + nodeValue = ((Integer) node.data).intValue(); + } + if (node.next == null) { + return; + } + Node temp = new Node(null, node);// 大于min的不是最后元素则用temp.next记录当前位置 + node = node.next; + nodeValue = ((Integer) node.data).intValue(); + while (nodeValue < max) { + node = node.next; + size--; + if (node == null) { + temp.next.next = node; + return; + } + nodeValue = ((Integer) node.data).intValue(); + } + temp.next.next = node; + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + if (list == null) { + return list; + } + LinkedList result = new LinkedList(); + for (int i = 0; i < size(); i++) { + for (int j = 0; j < list.size(); j++) { + if (get(i).equals(list.get(j))) { + result.add(get(i)); + break; + } + } + } + return result; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("["); + for (int i = 0; i < size(); i++) { + if (i == size() - 1) { + sb.append(get(i)); + break; + } + sb.append(get(i)); + sb.append(","); + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/group15/1513_121469918/HomeWork01/.classpath b/group15/1513_121469918/HomeWork01/.classpath deleted file mode 100644 index fb565a588d..0000000000 --- a/group15/1513_121469918/HomeWork01/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/group15/1513_121469918/HomeWork01/.gitignore b/group15/1513_121469918/HomeWork01/.gitignore deleted file mode 100644 index ae3c172604..0000000000 --- a/group15/1513_121469918/HomeWork01/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin/ diff --git a/group15/1513_121469918/HomeWork01/.project b/group15/1513_121469918/HomeWork01/.project deleted file mode 100644 index 2865c24f37..0000000000 --- a/group15/1513_121469918/HomeWork01/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - HomeWork01 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/group15/1513_121469918/HomeWork01/.settings/org.eclipse.core.resources.prefs b/group15/1513_121469918/HomeWork01/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index bcb09d4d64..0000000000 --- a/group15/1513_121469918/HomeWork01/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/coding/ArrayList.java=GBK -encoding//src/coding/BinaryTreeNode.java=GBK -encoding//src/coding/Iterator.java=GBK -encoding//src/coding/LinkedList.java=GBK -encoding//src/coding/List.java=GBK -encoding//src/coding/Queue.java=GBK -encoding//src/coding/Stack.java=GBK diff --git a/group15/1513_121469918/HomeWork01/.settings/org.eclipse.jdt.core.prefs b/group15/1513_121469918/HomeWork01/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 7341ab1683..0000000000 --- a/group15/1513_121469918/HomeWork01/.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.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -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.7 diff --git a/group15/1513_121469918/HomeWork01/src/coding/Queue.java b/group15/1513_121469918/HomeWork01/src/coding/Queue.java deleted file mode 100644 index f4b6faaa8a..0000000000 --- a/group15/1513_121469918/HomeWork01/src/coding/Queue.java +++ /dev/null @@ -1,35 +0,0 @@ -package coding; - -import java.util.NoSuchElementException; - -public class Queue { - private int size; - private LinkedList list = new LinkedList(); - - public void enQueue(Object o){ - list.addLast(o);; - size++; - } - - public Object deQueue(){ - if(size<=0){ - throw new NoSuchElementException(); - } - Object val = list.removeFirst(); - size--; - return val; - } - - public boolean isEmpty(){ - boolean flag = false; - if(size >= 0){ - flag = true; - } - return flag; - } - - public int size(){ - return size; - } - -} diff --git a/group15/1513_121469918/HomeWork20170305/.classpath b/group15/1513_121469918/HomeWork20170305/.classpath deleted file mode 100644 index a851141e9a..0000000000 --- a/group15/1513_121469918/HomeWork20170305/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/group15/1513_121469918/HomeWork20170305/.project b/group15/1513_121469918/HomeWork20170305/.project deleted file mode 100644 index 0e4fe1fc91..0000000000 --- a/group15/1513_121469918/HomeWork20170305/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - HomeWork20170305 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.core.resources.prefs b/group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 67f156c482..0000000000 --- a/group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/com/coderising/array/ArrayUtil.java=UTF-8 -encoding//src/com/coding/basic/ArrayList.java=GBK -encoding//src/com/coding/basic/BinaryTreeNode.java=GBK -encoding//src/com/coding/basic/Iterator.java=GBK -encoding//src/com/coding/basic/LinkedList.java=GBK -encoding//src/com/coding/basic/List.java=GBK -encoding//src/com/coding/basic/Queue.java=GBK -encoding//src/com/coding/basic/Stack.java=GBK diff --git a/group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.jdt.core.prefs b/group15/1513_121469918/HomeWork20170305/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 7341ab1683..0000000000 --- a/group15/1513_121469918/HomeWork20170305/.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.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -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.7 diff --git a/group15/1513_121469918/HomeWork20170305/bin/com/coderising/litestruts/struts.xml b/group15/1513_121469918/HomeWork20170305/bin/com/coderising/litestruts/struts.xml deleted file mode 100644 index a7cb57e188..0000000000 --- a/group15/1513_121469918/HomeWork20170305/bin/com/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/struts.xml b/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/struts.xml deleted file mode 100644 index a7cb57e188..0000000000 --- a/group15/1513_121469918/HomeWork20170305/src/com/coderising/litestruts/struts.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/ArrayList.java b/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/ArrayList.java deleted file mode 100644 index 951b1ce0e9..0000000000 --- a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/ArrayList.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -public class ArrayList implements List { - - private int size = 0; - - private Object[] elementData = new Object[100]; - - public void add(Object o) { - int len = size + 1; - // жlistijǷ - if (len > elementData.length) { - // - Object[] newElemDate = new Object[elementData.length + 1]; - // ƾԪص - System.arraycopy(elementData, 0, newElemDate, 0, elementData.length); - elementData = newElemDate; - } - elementData[size] = o; - size++; - } - - public void add(int index, Object o) { - // ǷԽ - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("index:" + index + "size:" + size); - } - // Ԫصĩβֱӵadd - if (index == size) { - add(o); - } else { - // - Object[] newElemData = new Object[elementData.length + 1]; - // indexǰԪص - System.arraycopy(elementData, 0, newElemData, 0, index); - newElemData[index] = o; - // index ԺԪص - System.arraycopy(elementData, index, newElemData, index + 1, size - index); - - elementData = newElemData; - size++; - } - } - - public Object get(int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("index:" + index + "size:" + size); - } - return elementData[index]; - } - - public Object remove(int index) { - if (index >= size) { - throw new IndexOutOfBoundsException("index:" + index + "size:" + size); - } - Object removeElement = elementData[index]; - //һԪصֵҪ - if(index != (size-1)){ - // - Object[] newElemData = new Object[elementData.length]; - // indexǰԪص - System.arraycopy(elementData, 0, newElemData, 0, index); - // index ԺԪص - System.arraycopy(elementData, index+1, newElemData, index, size - index -1); - } - //һԪصֱֵӼlist - size--; - return removeElement; - } - - public int size() { - return size; - } - - public Iterator iterator() { - return new MyIterator(this); - } - - private class MyIterator implements Iterator { - private int poi = -1; - private ArrayList array = null; - - private MyIterator(ArrayList array) { - this.array = array; - } - - @Override - public boolean hasNext() { - return (poi + 1) < array.size; - } - - @Override - public Object next() { - // TODO Auto-generated method stub - poi++; - if (poi >= array.size) { - poi--; - throw new IndexOutOfBoundsException(); - } - - return array.get(poi); - } - - @Override - public Object remove() { - // TODO Auto-generated method stub - if (poi < 0) { - throw new NoSuchElementException(); - } - Object val = array.remove(poi); - poi--; - return val; - } - - } -} diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/LinkedList.java b/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/LinkedList.java deleted file mode 100644 index d8f759fdcb..0000000000 --- a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/LinkedList.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -public class LinkedList implements List { - private Node head; - private int size; - - public void add(Object o) { - // жͷǷ - if (head == null) { - head = new Node(o, null); - } else { - Node newNode = head; - while (newNode.next != null) { - newNode = newNode.next; - } - newNode.next = new Node(o, null); - } - size++; - } - - public void add(int index, Object o) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("index:" + index + "size:" + size); - } - Node node = head; - if (index != 0) { - // ǵһֵҵֵǰһڵ - for (int i = 1; i < index; i++) { - node = node.next; - } - Node newNode = new Node(o, node.next); - node.next = newNode; - size++; - } else { - // һֵͽͷڵָ - Node newNode = new Node(o, head); - head = newNode; - size++; - } - } - - public Object get(int index) { - indexCheck(index); - Node node = head; - for (int i = 1; i <= index; i++) { - node = node.next; - } - return node.data; - } - - public Object remove(int index) { - indexCheck(index); - - Node node = head; - Node removeNode; - if (index == 0) { - //ɾһڵͰͷڵָԭĵڶڵ - removeNode = head; - head = head.next; - } else { - //ҵֵǰһڵ - for (int i = 1; i < index; i++) { - node = node.next; - } - removeNode = node.next; - //ǰһڵָ룬ָɾڵָĽڵ - node.next = removeNode.next; - } - size--; - return removeNode.data; - } - - public int size() { - return size; - } - - public void addFirst(Object o) { - Node newNode = new Node(o, head.next); - head.next = newNode; - size++; - } - - public void addLast(Object o) { - add(o); - } - - public Object removeFirst() { - //ûԪؾ쳣 - if (size <= 0) { - throw new IndexOutOfBoundsException("size:" + size); - } - Object val = head.data; - head = head.next; - size--; - return val; - } - - public Object removeLast() { - if (size <= 0) { - throw new IndexOutOfBoundsException("size:" + size); - } - Node node = head; - while (node.next != null) { - node = node.next; - } - Object val = node.data; - node = null; - size--; - return val; - } - - public Iterator iterator() { - return new MyIterator(this); - } - - private class MyIterator implements Iterator{ - private int poi = -1; - private LinkedList list ; - private MyIterator(LinkedList list) { - this.list= list; - } - @Override - public boolean hasNext() { - // TODO Auto-generated method stub - return (poi + 1) < list.size; - } - - @Override - public Object next() { - // TODO Auto-generated method stub - poi++; - if (poi >= list.size) { - poi--; - throw new IndexOutOfBoundsException(); - } - - return list.get(poi); - } - - @Override - public Object remove() { - // TODO Auto-generated method stub - if (poi < 0) { - throw new NoSuchElementException(); - } - Object val = list.removeLast(); - poi--; - return val; - } - - } - - private void indexCheck(int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("index:" + index + "size:" + size); - } - } - - private static class Node { - Object data; - Node next; - - Node(Object data, Node next) { - this.data = data; - this.next = next; - } - } -} diff --git a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Stack.java b/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Stack.java deleted file mode 100644 index 9a28ee4d36..0000000000 --- a/group15/1513_121469918/HomeWork20170305/src/com/coding/basic/Stack.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.coding.basic; - -import java.util.NoSuchElementException; - -public class Stack { - private ArrayList elementData = new ArrayList(); - private int size; - - public void push(Object o){ - elementData.add(o); - size++; - } - - public Object pop(){ - if(size<=0){ - throw new NoSuchElementException(); - } - int len = size-1; - Object val = elementData.remove(len); - size--; - return val; - } - - public Object peek(){ - if(size<=0){ - throw new NoSuchElementException(); - } - int len = size-1; - return elementData.get(len); - } - public boolean isEmpty(){ - boolean flag = false; - if(size >= 0){ - flag = true; - } - return flag; - } - public int size(){ - return size; - } -} diff --git a/group15/1515_337959725/.classpath b/group15/1515_337959725/.classpath index 6a4228528e..2d7497573f 100644 --- a/group15/1515_337959725/.classpath +++ b/group15/1515_337959725/.classpath @@ -1,7 +1,7 @@ - + diff --git a/group15/1515_337959725/.project b/group15/1515_337959725/.project index 6730933705..b6d8ce6204 100644 --- a/group15/1515_337959725/.project +++ b/group15/1515_337959725/.project @@ -1,6 +1,6 @@ - coding0305 + coding2017 diff --git a/group15/1515_337959725/.settings/org.eclipse.jdt.core.prefs b/group15/1515_337959725/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 060c5ee3d2..0000000000 --- a/group15/1515_337959725/.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.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -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.5 diff --git a/group15/1515_337959725/src/com/coderising/download/DownloadThread.java b/group15/1515_337959725/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..9d24d7d020 --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,27 @@ +package com.coderising.download; + +import java.io.IOException; + +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(){ + try { + byte[] read = conn.read(startPos, endPos); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/group15/1515_337959725/src/com/coderising/download/FileDownloader.java b/group15/1515_337959725/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..b892cea185 --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,77 @@ +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, Ƕ߳أ Ŀͻ˲֪ʲôʱҪʵֵ + // ̶ִ߳Ժ listenernotifiedFinished ͻ˾յ֪ͨ + // ʵ˼· + // 1. ҪConnectionManageropenӣ ȻͨConnection.getContentLengthļij + // 2. 3߳أ עÿ߳ҪȵConnectionManageropen + // Ȼread readжȡļĿʼλúͽλõIJ ֵbyte[] + // 3. byteд뵽ļ + // 4. е̶߳Ժ ҪlistenernotifiedFinished + + // Ĵʾ룬 Ҳ˵ֻһ̣߳ Ҫɶ̵߳ġ + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + int one=length/3; + + new DownloadThread(conn,0,one).start(); + new DownloadThread(conn,one+1,one*2+1).start(); + new DownloadThread(conn,(one+1)*2,length).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/group15/1515_337959725/src/com/coderising/download/FileDownloaderTest.java b/group15/1515_337959725/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..e3c94fd679 --- /dev/null +++ b/group15/1515_337959725/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/C:/Users/lyz/Desktop"; + + 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/group15/1515_337959725/src/com/coderising/download/api/Connection.java b/group15/1515_337959725/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..6a56145ddb --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/api/Connection.java @@ -0,0 +1,24 @@ +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; + /** + * õݵij + * @return + */ + public int getContentLength(); + + /** + * ر + */ + public void close(); +} + diff --git a/group15/1515_337959725/src/com/coderising/download/api/ConnectionException.java b/group15/1515_337959725/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group15/1515_337959725/src/com/coderising/download/api/ConnectionManager.java b/group15/1515_337959725/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..2fcad26a6b --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,11 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * һurl , һ + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} + diff --git a/group15/1515_337959725/src/com/coderising/download/api/DownloadListener.java b/group15/1515_337959725/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group15/1515_337959725/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/group15/1515_337959725/src/com/coderising/download/impl/ConnectionImpl.java b/group15/1515_337959725/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..bf59420685 --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,48 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + + private URL url; + + + public ConnectionImpl(URL url) { + this.url = url; + } + + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + byte[] b=new byte[1024*1024*10]; + InputStream is = url.openConnection().getInputStream(); + is.skip(startPos); + while((is.read(b,0, endPos-startPos))!=-1); + return b; + } + + @Override + public int getContentLength() { + int length=0; + try { + byte[] b=new byte[1024*1024*10]; + InputStream is = url.openConnection().getInputStream(); + while((length = is.read(b, 0, 1024*1024*10))!=-1); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return length; + } + + @Override + public void close() { + + + } + +} diff --git a/group15/1515_337959725/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group15/1515_337959725/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..89ae0edb72 --- /dev/null +++ b/group15/1515_337959725/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,31 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + URL urll = null; + try { + urll=new URL(url); +// URLConnection urlConnection = urll.openConnection(); + + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return new ConnectionImpl(urll); + } + +} diff --git a/group15/1515_337959725/src/com/coding/basic/SingleLinkedList.java b/group15/1515_337959725/src/com/coding/basic/SingleLinkedList.java new file mode 100644 index 0000000000..5f456856f7 --- /dev/null +++ b/group15/1515_337959725/src/com/coding/basic/SingleLinkedList.java @@ -0,0 +1,252 @@ +package com.coding.basic; + +public class SingleLinkedList{ + + //̬ڲʾĽڵ + private static class Node{ + public T date; // + Node next; //ָ + + public Node(T d){ + date = d; + next = null; + } + } + + private int theSize; + private Node head; + + public SingleLinkedList() + { + clear(); + } + // + public void clear(){ + theSize = 0; + head = null; + } + + //С + public int size(){ + return theSize; + } + + //ӽ + public void add(T x){ + Node newNode = new Node(x); + if(head == null){ + head = newNode ; + }else { + Node pNode = head; + while(pNode.next!=null){ + pNode = pNode.next; + } + pNode.next = newNode; + } + theSize++; + } + + //ڵ + public void add(int index ,T x){ + checkRange(index); + Node pNode = getNode(index); + Node newNode = new Node(x); + newNode.next = pNode.next; + pNode.next = newNode; + theSize++; + } + + //ͷڵ + public void addFirst(T x){ + Node newNode = new Node(x); + newNode.next = head; + head =newNode; + theSize++; + } + + //indexǷԽ + public void checkRange(int index){ + if (index<0 || index > size()) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + private String outOfBoundsMsg(int index) { + return "Index: "+index+", Size: "+size(); + } + + //ȡڵ + public T get(int index){ + Node pNode = getNode(index); + return pNode.date; + } + + //ȡڵ + public Node getNode(int index){ + checkRange(index); + Node pNode = head; + for(int i=0;i pNode = getNode(index); + T t=pNode.date; + Node temp = head; + for(int i=0;i7->10 , úΪ 10->7->3 + */ + public void reverse(){ + T t; + for(int i=0;i node1 = getNode(i); + Node node2 = getNode(theSize-1-i); + node1.date = node2.date; + node2.date=t; + } + } + + /** + * ɾһǰ벿 + * 磺list = 2->5->7->8 , ɾԺֵΪ 7->8 + * list = 2->5->7->8->10 ,ɾԺֵΪ7,8,10 + + */ + public void removeFirstHalf(){ + int count=theSize/2; + for(int i=0;i101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * صĽӦ[101,301,401,601] + * @param list + */ + public int[] getElements(SingleLinkedList list){ + int a; + int length=0; + int[] b=new int[theSize]; + for(int i=0;imin||a c=new SingleLinkedList(); + for(int i=0;i parameters) { * */ SAXReader reader = new SAXReader(); try { - Document document = reader.read(new File("src/com/coderising/litestruts/struts.xml")); + Document document = reader.read(new File("src/com/coderising/litestruts/struts.xml")); //re:创建一个java类来接收 Element root = document.getRootElement(); Iterator iter = root.elementIterator(); while(iter.hasNext()){ diff --git a/group15/1517_279137987/src/my/collection/linear/LinkedList.java b/group15/1517_279137987/src/my/collection/linear/LinkedList.java new file mode 100644 index 0000000000..1db8bd1053 --- /dev/null +++ b/group15/1517_279137987/src/my/collection/linear/LinkedList.java @@ -0,0 +1,218 @@ +package my.collection.linear; + +public class LinkedList implements MyList { + + private Node head; + + private int size = 0; + + public void add(Object obj) { + add(this.size, obj); + } + + public void add(int index, Object obj) { + Node curNode = head; + Node addNode = new Node(obj); + if(index == 0){ + addNode.next = head; + head = addNode; + }else{ + for(int i=0; i7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + for(int i=size; i>0; i--){ + this.add(get(i-1)); + } + this.removeFirstHalf(); + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + int removeCount = this.size()/2; + for(int i=0; i101->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 && Integer.parseInt(get(i).toString()) < max){ + remove(i); + i--; + } + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + LinkedList c = new LinkedList(); + for(int i=0; i - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - - /jsp/welcome.jsp - /jsp/error.jsp - - \ No newline at end of file diff --git a/group15/1521_653895972/src/com/coding/basic/ArrayList.java b/group15/1521_653895972/src/task1/basic/WArrayList.java similarity index 83% rename from group15/1521_653895972/src/com/coding/basic/ArrayList.java rename to group15/1521_653895972/src/task1/basic/WArrayList.java index 2b692ab814..d1ba8c5d63 100644 --- a/group15/1521_653895972/src/com/coding/basic/ArrayList.java +++ b/group15/1521_653895972/src/task1/basic/WArrayList.java @@ -1,13 +1,14 @@ -package com.coding.basic; +package task1.basic; import java.util.Arrays; import java.util.NoSuchElementException; +import java.util.Objects; /** * Created by wanc on 2017/2/21. * 实现ArrayList */ -public class ArrayList implements List { +public class WArrayList implements WList { /** * 实例化空数组 不用每次都new */ @@ -21,10 +22,15 @@ public class ArrayList implements List { */ private Object[] elementData = new Object[100]; - public ArrayList() { + public WArrayList() { this.elementData = Empty_elementData; } + public WArrayList(Object[] c) { + size = c.length; + this.elementData = c; + } + /** * 检查是否越界 */ @@ -108,17 +114,26 @@ public int size() { return size; } + public boolean contaions(Object o) { + if (size==0)return false; + for (int i = 0; i < size; i++) { + if (Objects.equals(o, elementData[i])) + return true; + } + return false; + } + /** * 获取迭代器 * * @return */ - public Iterator iterator() { + public WIterator iterator() { return new ArrayItr(); } //迭代器实现类部类 - private class ArrayItr implements Iterator { + private class ArrayItr implements WIterator { int cursor;//游标 @Override @@ -130,7 +145,7 @@ public boolean hasNext() { public Object next() { int i = cursor; if (i > size) throw new NoSuchElementException(); - Object[] newElementData = ArrayList.this.elementData; + Object[] newElementData = WArrayList.this.elementData; if (i > newElementData.length) throw new IndexOutOfBoundsException(); cursor = i + 1; return newElementData[i]; diff --git a/group15/1521_653895972/src/com/coding/basic/BinaryTreeNode.java b/group15/1521_653895972/src/task1/basic/WBinaryTreeNode.java similarity index 97% rename from group15/1521_653895972/src/com/coding/basic/BinaryTreeNode.java rename to group15/1521_653895972/src/task1/basic/WBinaryTreeNode.java index 34d76db083..207ccb7828 100644 --- a/group15/1521_653895972/src/com/coding/basic/BinaryTreeNode.java +++ b/group15/1521_653895972/src/task1/basic/WBinaryTreeNode.java @@ -1,11 +1,11 @@ -package com.coding.basic; +package task1.basic; /** * 实现二叉树 * left总比父节点小 * right总比父节点大 */ -public class BinaryTreeNode { +public class WBinaryTreeNode { private Node root; private int size = 0; diff --git a/group15/1521_653895972/src/task1/basic/WIterator.java b/group15/1521_653895972/src/task1/basic/WIterator.java new file mode 100644 index 0000000000..0f6b64a99f --- /dev/null +++ b/group15/1521_653895972/src/task1/basic/WIterator.java @@ -0,0 +1,7 @@ +package task1.basic; + +public interface WIterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group15/1521_653895972/src/com/coding/basic/LinkedList.java b/group15/1521_653895972/src/task1/basic/WLinkedList.java similarity index 53% rename from group15/1521_653895972/src/com/coding/basic/LinkedList.java rename to group15/1521_653895972/src/task1/basic/WLinkedList.java index f1f942590d..9afe3add71 100644 --- a/group15/1521_653895972/src/com/coding/basic/LinkedList.java +++ b/group15/1521_653895972/src/task1/basic/WLinkedList.java @@ -1,12 +1,14 @@ -package com.coding.basic; +package task1.basic; +import java.util.ConcurrentModificationException; import java.util.NoSuchElementException; +import java.util.Objects; /** * Created by wanc on 2017/2/21. * 实现单向链表集合 */ -public class LinkedList implements List { +public class WLinkedList implements WList { /** * 首节点 */ @@ -142,6 +144,14 @@ public Object remove(int index) { size--; return x.data; } + public Object remove(Object element){ + Node x=head; + for (int i=0;i size - 1) throw new NoSuchElementException(); + if (i > (size - 1)) throw new NoSuchElementException(); Node current = node(i); if (current == null) throw new IndexOutOfBoundsException(); + delCursor = i; cursor = i + 1; +// System.out.println("i="+i+"-"+current.data); return current.data; } + + @Override + public void remove() { + if (delCursor < 0) { + throw new IllegalStateException(); + } + try { + WLinkedList.this.remove(delCursor); + if (cursor > 0) + cursor--; + delCursor = -1; + } catch (IndexOutOfBoundsException e) { + throw new ConcurrentModificationException(); + } + + } } /** @@ -268,4 +301,123 @@ public String toString() { return result + "]"; } + + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (head == null) return; + Node[] nodes = new Node[size]; + Node x = head; + for (int i = 0; i < size; i++) { + nodes[i] = x; + x = x.next; + } + + head = nodes[nodes.length - 1]; + Node tmp = head; + for (int j = nodes.length - 2; j >= 0; j--) { + Node c = nodes[j]; + tmp.next = c; + tmp = c; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + int len = size / 2; + remove(0, len); + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + checkElementIndex(i); + checkElementIndex(i + length - 1); + if (0 == length) return; + int a = i - 1; + Node p = node(a);//前一个 + Node f = p.next;//删除第一个 + Node l = node(i + length - 1);//删除最后一个 + Node h = l.next;//后一个 + //去掉引用 等待GC回收 + Node tmp = f; + while (tmp != l) { + Node n = tmp.next; + tmp.next = null; + tmp = n; + } + l.next = null; + + if (0 == i) + head = h; + else + p.next = h; + 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(WLinkedList list) { + if (list == null) return null; + int[] arr = new int[list.size]; + WIterator itr = list.iterator(); + int i = 0; + while (itr.hasNext()) { + arr[i] = (int) node((int) itr.next()).data; + i++; + } + return arr; + } + + interface ListWIterator extends WIterator { + void remove(); + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(WLinkedList list) { + if (list != null && list.size > 0) { + WIterator itr = list.iterator(); + while (itr.hasNext()) { + ListWIterator sourItr = listIterator(); + Object value = itr.next(); + while (sourItr.hasNext()) { + Object souValue = sourItr.next(); +// System.out.println(value+"-"+souValue); + if (value.equals(souValue)) { +// System.out.println(value+"-"+sourItr.next()); + sourItr.remove(); +// System.out.println("remove"); + } + } +// System.out.println("---------------------------------"); + } + } + } + + } diff --git a/group15/1521_653895972/src/task1/basic/WList.java b/group15/1521_653895972/src/task1/basic/WList.java new file mode 100644 index 0000000000..f7534934d2 --- /dev/null +++ b/group15/1521_653895972/src/task1/basic/WList.java @@ -0,0 +1,9 @@ +package task1.basic; + +public interface WList { + 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/group15/1521_653895972/src/com/coding/basic/Queue.java b/group15/1521_653895972/src/task1/basic/WQueue.java similarity index 89% rename from group15/1521_653895972/src/com/coding/basic/Queue.java rename to group15/1521_653895972/src/task1/basic/WQueue.java index 4add2be9a4..af3fdb8302 100644 --- a/group15/1521_653895972/src/com/coding/basic/Queue.java +++ b/group15/1521_653895972/src/task1/basic/WQueue.java @@ -1,14 +1,14 @@ -package com.coding.basic; +package task1.basic; /** * Created by wanc on 2017/2/21. * 利用LinkedList 实现队列 */ -public class Queue { +public class WQueue { /** * 利用LinkedList 保存数据 */ - private LinkedList elementData = new LinkedList(); + private WLinkedList elementData = new WLinkedList(); /** * 入队 diff --git a/group15/1521_653895972/src/com/coding/basic/Stack.java b/group15/1521_653895972/src/task1/basic/WStack.java similarity index 90% rename from group15/1521_653895972/src/com/coding/basic/Stack.java rename to group15/1521_653895972/src/task1/basic/WStack.java index 23c5ba6a7b..a6bb09ed77 100644 --- a/group15/1521_653895972/src/com/coding/basic/Stack.java +++ b/group15/1521_653895972/src/task1/basic/WStack.java @@ -1,13 +1,13 @@ -package com.coding.basic; +package task1.basic; /** * Created by wanc on 2017/2/21. * 利用ArrayList 实现栈 */ -public class Stack { +public class WStack { /** * 利用ArrayList 保存数据 */ - private ArrayList elementData = new ArrayList(); + private WArrayList elementData = new WArrayList(); /** * 入栈 diff --git a/group15/1521_653895972/src/com/coding/basic/BasicTest.java b/group15/1521_653895972/src/task1/test/BasicTest.java similarity index 92% rename from group15/1521_653895972/src/com/coding/basic/BasicTest.java rename to group15/1521_653895972/src/task1/test/BasicTest.java index a181087104..f5143acc7f 100644 --- a/group15/1521_653895972/src/com/coding/basic/BasicTest.java +++ b/group15/1521_653895972/src/task1/test/BasicTest.java @@ -1,7 +1,8 @@ -package com.coding.basic; +package task1.test; import org.junit.Assert; import org.junit.Test; +import task1.basic.*; /** * Created by wanc on 2017/2/21. @@ -11,16 +12,16 @@ public class BasicTest { @Test public void test() { //测试 - testArrayList(); +// testArrayList(); testLinkedList(); - testBinaryTreeNode(); - testStack(); - testQueue(); +// testBinaryTreeNode(); +// testStack(); +// testQueue(); } public void testQueue(){ - Queue queue = new Queue(); + WQueue queue = new WQueue(); queue.enQueue("S"); queue.enQueue("Y"); queue.enQueue(5); @@ -32,7 +33,7 @@ public void testQueue(){ System.out.println(queue); } public void testStack(){ - Stack stack = new Stack(); + WStack stack = new WStack(); stack.push("S"); stack.push("Y"); stack.push(5); @@ -46,7 +47,7 @@ public void testStack(){ public void testBinaryTreeNode(){ System.out.println("-------------------BinaryTreeNode 测试开始-------------------"); System.out.println("new 一个实例"); - BinaryTreeNode root = new BinaryTreeNode(); + WBinaryTreeNode root = new WBinaryTreeNode(); root.insert(5); root.insert(6); root.insert(9); @@ -61,7 +62,7 @@ public void testLinkedList() { System.out.println("-------------------LinkedList 测试开始-------------------"); System.out.println("new 一个实例"); - LinkedList list = new LinkedList(); + WLinkedList list = new WLinkedList(); System.out.println("添加元素----A"); list.add("A"); @@ -125,7 +126,7 @@ public void testLinkedList() { System.out.println(); System.out.println("迭代器输出:"); - Iterator i = list.iterator(); + WIterator i = list.iterator(); while (i.hasNext()){ System.out.print(i.next()+" "); } @@ -139,7 +140,7 @@ public void testArrayList() { System.out.println("-------------------ArrayList 测试开始-------------------"); System.out.println("new 一个实例"); - ArrayList list = new ArrayList(); + WArrayList list = new WArrayList(); System.out.println("添加元素 A"); list.add("A"); @@ -174,7 +175,7 @@ public void testArrayList() { System.out.println("输出:"+list); System.out.println("数量:"+list.size()); - Iterator i = list.iterator(); + WIterator i = list.iterator(); System.out.print("迭代器输出:"); while (i.hasNext()){ System.out.print(i.next()+" "); diff --git a/group15/1521_653895972/src/task1/test/WLinkedListTest.java b/group15/1521_653895972/src/task1/test/WLinkedListTest.java new file mode 100644 index 0000000000..33fddb06e3 --- /dev/null +++ b/group15/1521_653895972/src/task1/test/WLinkedListTest.java @@ -0,0 +1,98 @@ +package task1.test; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import task3.basic.WLinkedList; + +import java.util.Arrays; + +/** + * Created by wanc on 2017/3/7. + * 3月5日 布置的数据结构作业测试 + */ +public class WLinkedListTest { + WLinkedList list; + + @Before + public void setUp() throws Exception { + list = new WLinkedList(); + 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.add(701); + list.add(301); + System.out.println(list); + } + + @After + public void tearDown() throws Exception { + + + } + + + @Test + public void testReverse() throws Exception { + list.reverse(); + System.out.println(list); + } + + @Test + public void testRemoveFirstHalf() throws Exception { + list.removeFirstHalf(); + System.out.println(list); + } + + @Test + public void testRemove() throws Exception { + list.remove(3,4); + System.out.println(list); + } + + @Test + public void testGetElements() throws Exception { + WLinkedList lst = new WLinkedList(); + lst.add(1); + lst.add(3); + lst.add(4); + lst.add(6); + int[] elements = list.getElements(lst); + System.out.println(Arrays.toString(elements)); + } + + @Test + public void testSubtract() throws Exception { + WLinkedList lst = new WLinkedList(); + lst.add(101); + lst.add(301); + lst.add(401); + lst.add(601); + list.subtract(lst); + System.out.println(list); + } + + @Test + public void testRemoveDuplicateValues() throws Exception { + list.add(301); + list.add(401); + System.out.println(list); + list.removeDuplicateValues(); + System.out.println(list); + } + + @Test + public void testRemoveRange() throws Exception { + + } + + @Test + public void testIntersection() throws Exception { + + } +} \ No newline at end of file diff --git a/group15/1521_653895972/src/com/coding/coderising/array/ArrayUtilTest.java b/group15/1521_653895972/src/task2/array/ArrayUtilTest.java similarity index 98% rename from group15/1521_653895972/src/com/coding/coderising/array/ArrayUtilTest.java rename to group15/1521_653895972/src/task2/array/ArrayUtilTest.java index 92c581254b..8b14cf6516 100644 --- a/group15/1521_653895972/src/com/coding/coderising/array/ArrayUtilTest.java +++ b/group15/1521_653895972/src/task2/array/ArrayUtilTest.java @@ -1,4 +1,4 @@ -package com.coding.coderising.array; +package task2.array; import org.junit.Test; diff --git a/group15/1521_653895972/src/com/coding/coderising/array/SimpleArrayUtil.java b/group15/1521_653895972/src/task2/array/SimpleArrayUtil.java similarity index 99% rename from group15/1521_653895972/src/com/coding/coderising/array/SimpleArrayUtil.java rename to group15/1521_653895972/src/task2/array/SimpleArrayUtil.java index 0aa491fb16..fa1b17e7ed 100644 --- a/group15/1521_653895972/src/com/coding/coderising/array/SimpleArrayUtil.java +++ b/group15/1521_653895972/src/task2/array/SimpleArrayUtil.java @@ -1,4 +1,4 @@ -package com.coding.coderising.array; +package task2.array; public class SimpleArrayUtil { diff --git a/group15/1521_653895972/src/com/coding/coderising/litestruts/LoginAction.java b/group15/1521_653895972/src/task2/litestruts/LoginAction.java similarity index 95% rename from group15/1521_653895972/src/com/coding/coderising/litestruts/LoginAction.java rename to group15/1521_653895972/src/task2/litestruts/LoginAction.java index 273741bbfb..3f7baf7842 100644 --- a/group15/1521_653895972/src/com/coding/coderising/litestruts/LoginAction.java +++ b/group15/1521_653895972/src/task2/litestruts/LoginAction.java @@ -1,4 +1,4 @@ -package com.coding.coderising.litestruts; +package task2.litestruts; /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 diff --git a/group15/1521_653895972/src/com/coding/coderising/litestruts/Struts.java b/group15/1521_653895972/src/task2/litestruts/Struts.java similarity index 99% rename from group15/1521_653895972/src/com/coding/coderising/litestruts/Struts.java rename to group15/1521_653895972/src/task2/litestruts/Struts.java index ed20c588fe..87c9d2a9ca 100644 --- a/group15/1521_653895972/src/com/coding/coderising/litestruts/Struts.java +++ b/group15/1521_653895972/src/task2/litestruts/Struts.java @@ -1,4 +1,4 @@ -package com.coding.coderising.litestruts; +package task2.litestruts; import org.w3c.dom.Document; import org.w3c.dom.Element; diff --git a/group15/1521_653895972/src/com/coding/coderising/litestruts/View.java b/group15/1521_653895972/src/task2/litestruts/View.java similarity index 91% rename from group15/1521_653895972/src/com/coding/coderising/litestruts/View.java rename to group15/1521_653895972/src/task2/litestruts/View.java index 2c909058cb..7663182dcc 100644 --- a/group15/1521_653895972/src/com/coding/coderising/litestruts/View.java +++ b/group15/1521_653895972/src/task2/litestruts/View.java @@ -1,4 +1,4 @@ -package com.coding.coderising.litestruts; +package task2.litestruts; import java.util.Map; diff --git a/group15/1521_653895972/src/task2/test/StrutsTest.java b/group15/1521_653895972/src/task2/test/StrutsTest.java new file mode 100644 index 0000000000..4bd28b08d4 --- /dev/null +++ b/group15/1521_653895972/src/task2/test/StrutsTest.java @@ -0,0 +1,45 @@ +package task2.test; + +import task2.litestruts.Struts; +import task2.litestruts.View; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + + + + + +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/group15/1521_653895972/src/task3/basic/WLinkedList.java b/group15/1521_653895972/src/task3/basic/WLinkedList.java new file mode 100644 index 0000000000..eff5fba7b9 --- /dev/null +++ b/group15/1521_653895972/src/task3/basic/WLinkedList.java @@ -0,0 +1,534 @@ +package task3.basic; + +import task1.basic.WIterator; +import task1.basic.WList; + +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; +import java.util.Objects; + +/** + * Created by wanc on 2017/2/21. + * 实现单向链表集合 + */ +public class WLinkedList implements WList { + /** + * 首节点 + */ + private Node head; + /** + * 计数 + */ + private int size = 0; + + /** + * 检查是否越界 利用jdk源码的检测方法 + */ + private boolean isElementIndex(int index) { + return index >= 0 && index < size; + } + + /** + * JDK 源码检测方法 + * + * @param index + * @return + */ + private boolean isPositionIndex(int index) { + return index >= 0 && index <= size; + } + + /** + * JDK 源码 错误信息 + * + * @param index + * @return + */ + private String outOfBoundsMsg(int index) { + return "Index: " + index + ", Size: " + size; + } + + /** + * JDK 源码检测方法 + * + * @param index + * @return + */ + private void checkElementIndex(int index) { + if (!isElementIndex(index)) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + /** + * JDK 源码检测方法 + * + * @param index + * @return + */ + private void checkPositionIndex(int index) { + if (!isPositionIndex(index)) + throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); + } + + /** + * 获取对应下标的节点 + */ + Node node(int index) { + Node x = head; + for (int i = 0; i < index; i++) + x = x.next; + return x; + } + + /** + * 在末尾添加数据 + * + * @param o + */ + public void add(Object o) { + + if (head == null) + head = new Node(o, null); + else { + final Node lastNode = node(size - 1); + final Node newNode = new Node(o, null); + lastNode.next = newNode; + } + size++; + } + + /** + * 指定位置添加数据 + * + * @param index + * @param o + */ + public void add(int index, Object o) { + checkPositionIndex(index); + if (size == index) + add(o); + else { + final Node prevNode = node(index - 1); + final Node nextNode = prevNode.next; + final Node newNode = new Node(o, nextNode); + prevNode.next = newNode; + size++; + } + } + + /** + * 获取指定索引数据 + * + * @param index + * @return + */ + public Object get(int index) { + return node(index).data; + } + + /** + * 移除指定索引数据 + * + * @param index + * @return + */ + public Object remove(int index) { + checkElementIndex(index); + final Node prevNode = node(index - 1); + final Node x = prevNode.next; + if (index - 1 < 0) { + prevNode.next = null; + head = x; + } else { + final Node nextNode = x.next; + prevNode.next = nextNode; + x.next = null; + } + size--; + return x.data; + } + + public Object remove(Object element) { + Node x = head; + for (int i = 0; i < size; i++) { + if (Objects.equals(x.data, element)) + x = x.next; + } + return null; + } + + /** + * 返回数量 + * + * @return + */ + public int size() { + return size; + } + + /** + * 在链首添加数据 + * + * @return + */ + public void addFirst(Object o) { + final Node h = head; + final Node newNode = new Node(o, h); + head = newNode; + size++; + } + + /** + * 在链尾添加数据 + * + * @return + */ + public void addLast(Object o) { + add(o); + } + + /** + * 移除链首数据 + * + * @return + */ + public Object removeFirst() { + final Node h = head; + if (h == null) + throw new NoSuchElementException(); + final Node newFirst = h.next; + h.next = null; + head = newFirst; + size--; + return h.data; + } + + /** + * 移除链尾数据 + * + * @return + */ + public Object removeLast() { + final Node prev = node(size - 1 - 1); + final Node l = prev.next; + prev.next = null; + l.next = null; + size--; + return l.data; + } + + /** + * 获取迭代器 + * + * @return + */ + public WIterator iterator() { + return new LinkedItr(); + } + + public ListWIterator listIterator() { + return new LinkedItr(); + } + + /** + * 迭代器实现内部类 + * + * @return + */ + private class LinkedItr implements ListWIterator { + int cursor = 0;//游标 + int delCursor = -1; + + @Override + public boolean hasNext() { + return cursor != size; + } + + @Override + public Object next() { + int i = cursor; + if (i > (size - 1)) throw new NoSuchElementException(); + Node current = node(i); + if (current == null) throw new IndexOutOfBoundsException(); + delCursor = i; + cursor = i + 1; +// System.out.println("i="+i+"-"+current.data); + return current.data; + } + + @Override + public void remove() { + if (delCursor < 0) { + throw new IllegalStateException(); + } + try { + WLinkedList.this.remove(delCursor); + if (cursor > 0) + cursor--; + delCursor = -1; + } catch (IndexOutOfBoundsException e) { + throw new ConcurrentModificationException(); + } + + } + } + + /** + * 节点内部类 用于保存数据 + */ + private static class Node { + Object data; + Node next; + + Node(Object data, Node next) { + this.data = data; + this.next = next; + } + } + + /** + * 重写toString 方便打印 + * + * @return + */ + @Override + public String toString() { + String elementStr = ""; + Node p = head; + while (p != null) { + elementStr += p.data + ","; + p = p.next; + } + + return "WLinkedList: { size=" + size + ", elementData=" + "[" + + elementStr.substring(0, elementStr.length() - 1) + "]" + " }"; + } + + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (head == null) return; + Node[] nodes = new Node[size]; + Node x = head; + for (int i = 0; i < size; i++) { + nodes[i] = x; + x = x.next; + } + + head = nodes[nodes.length - 1]; + Node tmp = head; + for (int j = nodes.length - 2; j >= 0; j--) { + Node c = nodes[j]; + tmp.next = c; + tmp = c; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + int len = size / 2; + remove(0, len); + + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + checkElementIndex(i); + checkElementIndex(i + length - 1); + if (0 == length) return; + int a = i - 1; + Node p = node(a);//前一个 + Node f = p.next;//删除第一个 + Node l = node(i + length - 1);//删除最后一个 + Node h = l.next;//后一个 + //去掉引用 等待GC回收 + Node tmp = f; + while (tmp != l) { + Node n = tmp.next; + tmp.next = null; + tmp = n; + } + l.next = null; + + if (0 == i) + head = h; + else + p.next = h; + 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(WLinkedList list) { + if (list == null) return null; + int[] arr = new int[list.size]; + WIterator itr = list.iterator(); + int i = 0; + while (itr.hasNext()) { + arr[i] = (int) node((int) itr.next()).data; + i++; + } + return arr; + } + + interface ListWIterator extends WIterator { + void remove(); + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(WLinkedList list) { + if (list != null && list.size > 0) { + WIterator itr = list.iterator(); + while (itr.hasNext()) { + ListWIterator sourItr = listIterator(); + Object value = itr.next(); + while (sourItr.hasNext()) { + Object souValue = sourItr.next(); +// System.out.println(value+"-"+souValue); + if (value.equals(souValue)) { +// System.out.println(value+"-"+sourItr.next()); + sourItr.remove(); +// System.out.println("remove"); + } + } +// System.out.println("---------------------------------"); + } + } + } + + public Object[] toArray() { + Object[] newObj = new Object[size]; + if (head == null) return new Object[]{}; + Node x = head; + for (int i = 0; i < size; i++) { + newObj[i] = x.data; + x = x.next; + } + return newObj; + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + if (head == null) return; + Node n1 = head; + Node n2 = head.next; + while (n1 != null && n2 != null) { + if (Objects.equals(n1.data, n2.data)) { + n2 = n2.next; + n1.next = n2; + size--; + } else { + n1 = n2; + n2 = n2.next; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + Node x = head; + boolean mingetflag = false; + boolean maxgetflag = false; + Node minEndNode = null; + Node maxStartNode = null; + while (x.next != null) { + if ((int) x.data <= min && !mingetflag) { + minEndNode = x; + }else { + mingetflag = true; + } + if ((int) x.data >= max && !maxgetflag) { + maxStartNode = x; + maxgetflag = true; + } + if (maxgetflag && mingetflag) + break; + x = x.next; + } + System.out.println(minEndNode.data + "-" + maxStartNode.data+"-"+maxStartNode.next.data); + if (minEndNode != null && maxStartNode != null) { + clear(minEndNode, maxStartNode); + } + if (minEndNode == null && maxStartNode != null) { + clear(null, maxStartNode); + } + if (minEndNode != null && maxStartNode == null) { + clear(minEndNode, null); + } + } + + private void clear(Node start, Node end) { + if (start == null) + start = head; + Node x = start.next; + while (x != null) { + if (end != null && Objects.equals(x.data, end.data)) { + break; + } + Node next = x.next; + x.data = null; + x.next = null; + x = next; + size--; + } + start.next = end; + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public WLinkedList intersection(WLinkedList list) { + WLinkedList result = new WLinkedList(); + Node n1=this.head,n2=list.head; + while (n1!=null&&n2!=null){ + if (Objects.equals(n1.data,n2.data)){ + result.add(n1.data); + n1=n1.next; + n2=n2.next; + }else if ((int)n1.data>(int)n2.data){ + n2=n2.next; + }else { + n1=n1.next; + } + } + return result; + } + +} diff --git a/group15/1521_653895972/src/task3/download/DownloadThread.java b/group15/1521_653895972/src/task3/download/DownloadThread.java new file mode 100644 index 0000000000..28c541c75e --- /dev/null +++ b/group15/1521_653895972/src/task3/download/DownloadThread.java @@ -0,0 +1,38 @@ +package task3.download; + +import task3.download.api.Connection; + +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread{ + Connection conn; + int startPos; + int endPos; + String targetPath; + + 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 targetPath) { + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.targetPath = targetPath; + } + + public void run(){ + try { + byte[] rs = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile(targetPath, "rw"); + raf.seek(startPos); + raf.write(rs, 0, rs.length); + raf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group15/1521_653895972/src/task3/download/FileDownloader.java b/group15/1521_653895972/src/task3/download/FileDownloader.java new file mode 100644 index 0000000000..a75186ade6 --- /dev/null +++ b/group15/1521_653895972/src/task3/download/FileDownloader.java @@ -0,0 +1,94 @@ +package task3.download; + +import task3.download.api.Connection; +import task3.download.api.ConnectionManager; +import task3.download.api.DownloadListener; + +import java.util.ArrayList; +import java.util.List; + + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + int startPos=0,endPos=0; + try { + conn = cm.open(this.url); + int length = conn.getContentLength(); + String targetPath = "G:\\wanc\\图片\\targetfile." + url.substring(url.lastIndexOf(".") + 1); + List list = new ArrayList<>(); + int size = 3; + for (int i = 0; i < size; i++) { + conn = cm.open(this.url); + startPos = i * (length / size); + endPos = (i == size - 1) ? length - 1 : (i + 1) * (length / size) - 1; + DownloadThread thread = new DownloadThread(conn, startPos, endPos, targetPath); + list.add(thread); + thread.start(); + } + + // 调用线程的join方法,保证所有的线程都结束后再发出结束通知 + for (int i = 0; i < list.size(); i++) { + try { + list.get(i).join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + listener.notifyFinished(); + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group15/1521_653895972/src/task3/download/api/Connection.java b/group15/1521_653895972/src/task3/download/api/Connection.java new file mode 100644 index 0000000000..e9ce626831 --- /dev/null +++ b/group15/1521_653895972/src/task3/download/api/Connection.java @@ -0,0 +1,23 @@ +package task3.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/group15/1521_653895972/src/task3/download/api/ConnectionException.java b/group15/1521_653895972/src/task3/download/api/ConnectionException.java new file mode 100644 index 0000000000..a9c2c5ef83 --- /dev/null +++ b/group15/1521_653895972/src/task3/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package task3.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group15/1521_653895972/src/task3/download/api/ConnectionManager.java b/group15/1521_653895972/src/task3/download/api/ConnectionManager.java new file mode 100644 index 0000000000..bb83d56a62 --- /dev/null +++ b/group15/1521_653895972/src/task3/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package task3.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException, Exception; +} diff --git a/group15/1521_653895972/src/task3/download/api/DownloadListener.java b/group15/1521_653895972/src/task3/download/api/DownloadListener.java new file mode 100644 index 0000000000..6d0cb69e7c --- /dev/null +++ b/group15/1521_653895972/src/task3/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package task3.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group15/1521_653895972/src/task3/download/impl/ConnectionImpl.java b/group15/1521_653895972/src/task3/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..c38ff387ee --- /dev/null +++ b/group15/1521_653895972/src/task3/download/impl/ConnectionImpl.java @@ -0,0 +1,55 @@ +package task3.download.impl; + +import task3.download.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 { + private HttpURLConnection conn; + + public ConnectionImpl(String urlString) { + URL targetUrl = null; + try { + targetUrl = new URL(urlString); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + try { + conn = (HttpURLConnection) targetUrl.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + //设置读取的文件块 + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream is = conn.getInputStream(); + ByteArrayOutputStream out =new ByteArrayOutputStream(); + int len=0; + byte[] buff = new byte[1024]; + while ((len = is.read(buff)) != -1) { + out.write(buff,0,len); + } + out.close(); + is.close(); + return out.toByteArray(); + } + + @Override + public int getContentLength() { + return conn.getContentLength(); + } + + @Override + public void close() { + conn.disconnect(); + } + +} diff --git a/group15/1521_653895972/src/task3/download/impl/ConnectionManagerImpl.java b/group15/1521_653895972/src/task3/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..a488f89561 --- /dev/null +++ b/group15/1521_653895972/src/task3/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,13 @@ +package task3.download.impl; + +import task3.download.api.Connection; +import task3.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws Exception { + return new ConnectionImpl(url); + } + +} diff --git a/group15/1521_653895972/src/task3/test/FileDownloaderTest.java b/group15/1521_653895972/src/task3/test/FileDownloaderTest.java new file mode 100644 index 0000000000..c37d9e318e --- /dev/null +++ b/group15/1521_653895972/src/task3/test/FileDownloaderTest.java @@ -0,0 +1,60 @@ +package task3.test; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import task3.download.FileDownloader; +import task3.download.api.ConnectionManager; +import task3.download.api.DownloadListener; +import task3.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://img.bizhi.sogou.com/images/1680x1050/2014/04/24/590270.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/group15/1521_653895972/src/task3/test/WLinkedListTest.java b/group15/1521_653895972/src/task3/test/WLinkedListTest.java new file mode 100644 index 0000000000..4f1959823e --- /dev/null +++ b/group15/1521_653895972/src/task3/test/WLinkedListTest.java @@ -0,0 +1,72 @@ +package task3.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import task3.basic.WLinkedList; + +/** + * Created by wanc on 2017/3/13. + */ +public class WLinkedListTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void testRemoveDuplicateValues() throws Exception { + WLinkedList wll = new WLinkedList(); + wll.add(11); + wll.add(12); + wll.add(12); + wll.add(13); + wll.add(14); + wll.add(14); + wll.add(15); + wll.removeDuplicateValues(); + Assert.assertArrayEquals(new Object[]{11,12,13,14,15},wll.toArray()); + } + + @Test + public void testRemoveRange() throws Exception { + WLinkedList wll = new WLinkedList(); + wll.add(11); + wll.add(12); + wll.add(13); + wll.add(14); + wll.add(15); + wll.add(16); + wll.add(17); + wll.removeRange(12,16); +// wll.removeRange2(12,16); + Assert.assertArrayEquals(new Object[]{11,12,16,17},wll.toArray()); + } + + @Test + public void testIntersection() throws Exception { + WLinkedList wll = new WLinkedList(); + wll.add(11); + wll.add(12); + wll.add(13); + wll.add(14); + wll.add(15); + wll.add(16); + wll.add(17); + WLinkedList wll2 = new WLinkedList(); + wll2.add(8); + wll2.add(10); + wll2.add(12); + wll2.add(14); + wll2.add(16); + wll2.add(18); + WLinkedList wll3 =wll.intersection(wll2); + Assert.assertArrayEquals(new Object[]{12,14,16},wll3.toArray()); + } +} \ No newline at end of file diff --git a/group16/1012075117/DataStructure219/.classpath b/group16/1012075117/DataStructure219/.classpath deleted file mode 100644 index fceb4801b5..0000000000 --- a/group16/1012075117/DataStructure219/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/group16/1012075117/DataStructure219/.project b/group16/1012075117/DataStructure219/.project deleted file mode 100644 index 567baae65f..0000000000 --- a/group16/1012075117/DataStructure219/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - DataStructure219 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/group16/1012075117/DataStructure219/.settings/org.eclipse.jdt.core.prefs b/group16/1012075117/DataStructure219/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 3a21537071..0000000000 --- a/group16/1012075117/DataStructure219/.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/group16/1012075117/src/com/coderising/download/DownloadThread.java b/group16/1012075117/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..d89e878fb0 --- /dev/null +++ b/group16/1012075117/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,49 @@ +package com.coderising.download; + +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; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class DownloadThread extends Thread { + + ConnectionManager cm; + Connection conn; + DownloadListener downloadListener; + int startPos; + int endPos; + String fileName; + String url; + + public DownloadThread(String url, int startPos, int endPos, String fileName, DownloadListener downloadListener) { + this.url = url; + this.startPos = startPos; + this.endPos = endPos; + this.fileName = fileName; + this.downloadListener = downloadListener; + } + + public void run() { + cm = new ConnectionManagerImpl(); + byte[] b = null; + RandomAccessFile randomAF = null; + try { + conn = cm.open(url); + b = conn.read(startPos, endPos); + randomAF = new RandomAccessFile(fileName, "rw"); + randomAF.seek(startPos); + randomAF.write(b); + randomAF.close(); + downloadListener.notifyFinished(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/group16/1012075117/src/com/coderising/download/FileDownloader.java b/group16/1012075117/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..7ff9ee2b29 --- /dev/null +++ b/group16/1012075117/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,116 @@ +package com.coderising.download; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +/** + * 实现多线程下载 - 第三次作业 + * @author stackwei + * @date 2017/4/3 + * @status ok + */ +public class FileDownloader { + + String url; + DownloadListener listener; + ConnectionManager cm; + AtomicInteger atomicInteger; + + public FileDownloader(String _url) { + this.url = _url; + atomicInteger = new AtomicInteger(); + } + + 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 = conn.getFileName(); + + int p2 = 0; + int p4 = 0; + if (length % 3 == 0) { + p2 = length / 3; + p4 = 2 * p2; + } else { + if((length - 1) % 3 == 0) { + p2 = (length - 1) / 3; + p4 = 2 * p2; + } else { + if((length - 2) % 3 == 0) { + p2 = (length - 2) / 3; + p4 = 2 * p2; + } + } + } + + atomicInteger.getAndIncrement(); + atomicInteger.getAndIncrement(); + atomicInteger.getAndIncrement(); + + new DownloadThread(url, 0, p2 , fileName, new DownloadListener() { + @Override + public void notifyFinished() { + if (atomicInteger.decrementAndGet() == 0) + FileDownloader.this.listener.notifyFinished(); + }; + }).start(); + + new DownloadThread(url, p2 + 1, p4, fileName, new DownloadListener() { + @Override + public void notifyFinished() { + if (atomicInteger.decrementAndGet() == 0) + FileDownloader.this.listener.notifyFinished(); + }; + }).start(); + + new DownloadThread(url, p4 + 1, length - 1, fileName, new DownloadListener() { + @Override + public void notifyFinished() { + if (atomicInteger.decrementAndGet() == 0) + FileDownloader.this.listener.notifyFinished(); + }; + }).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/group16/1012075117/src/com/coderising/download/FileDownloaderTest.java b/group16/1012075117/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..6445bdf48d --- /dev/null +++ b/group16/1012075117/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,40 @@ +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 { + boolean downloadFinished = false; + + @Test + public void testDownload() { + String url = "http://img3.cache.netease.com/photo/0038/2017-03-31/CGT4JVHJ5S400038.jpg"; + FileDownloader downloader = new FileDownloader(url); + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + }); + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + } + +} \ No newline at end of file diff --git a/group16/1012075117/src/com/coderising/download/api/Connection.java b/group16/1012075117/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..fb340f390d --- /dev/null +++ b/group16/1012075117/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(); + + /** + * 获取文件名 + * @return + */ + public String getFileName(); +} diff --git a/group16/1012075117/src/com/coderising/download/api/ConnectionException.java b/group16/1012075117/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group16/1012075117/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/1012075117/src/com/coderising/download/api/ConnectionManager.java b/group16/1012075117/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group16/1012075117/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/1012075117/src/com/coderising/download/api/DownloadListener.java b/group16/1012075117/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group16/1012075117/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/1012075117/src/com/coderising/download/impl/ConnectionImpl.java b/group16/1012075117/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..35dea6afdb --- /dev/null +++ b/group16/1012075117/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,65 @@ +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 httpURLConnection; + private InputStream inputstream; + String url; + + public ConnectionImpl(HttpURLConnection httpURLConnection, String url) { + this.httpURLConnection = httpURLConnection; + this.url = url; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + inputstream = httpURLConnection.getInputStream(); + int total = endPos - startPos + 1; + inputstream.skip(startPos); + byte[] bytes = new byte[total]; + int len = 0; + int hasRead = 0; + while ((len = inputstream.read(bytes, hasRead, total - hasRead)) > 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..6b576f0946 --- /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/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..025fcff47b --- /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..5cf6b374d6 --- /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..250fe011b7 --- /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/group24/798277403/src/week3/api/Connection.java b/group16/2816977791/thirdExercise/src/api/Connection.java similarity index 95% rename from group24/798277403/src/week3/api/Connection.java rename to group16/2816977791/thirdExercise/src/api/Connection.java index 9c67704364..828332de3b 100644 --- a/group24/798277403/src/week3/api/Connection.java +++ b/group16/2816977791/thirdExercise/src/api/Connection.java @@ -1,4 +1,4 @@ -package week3.api; +package api; import java.io.IOException; @@ -15,7 +15,7 @@ public interface Connection { * @return */ public int getContentLength(); - + /** * 关闭连接 */ diff --git a/group16/2816977791/thirdExercise/src/api/ConnectionException.java b/group16/2816977791/thirdExercise/src/api/ConnectionException.java new file mode 100644 index 0000000000..60a2043e44 --- /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..efb2f2ab6b --- /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..b8ab21d462 --- /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..699c5c6139 --- /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..ff364efd92 --- /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/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/coding/basic/ArrayList.java b/group16/313001956/src/com/coding/basic/ArrayList.java index 3bec144013a94278e6a7ef25d65622c3430e8e27..03d2547c307022a3f314f5d4698bb1328689b7c7 100644 GIT binary patch literal 1570 zcmcJO`#%#30L8Jisby}FkZALoZER-dk+6k4Vr(eF@|;KVF5weJm}nj`%A>qKY{_1wUUq-^kx! zYfrTKZGVJ0yC35a1kEAIc^2xZ?=;9)1OxHp5l}ss4_QMTl=)NqUxS>I!Bm@WNJxXN zS~_YPNlz5!A8hYeP2N~^iD7YGl7;D=7Sh>(*MWI)+~=!EcsgAq@Wb*{!YbZ)aTOKqGfEE#RL!*xQtjml$iFj zp}1A7cs!N}I%>p#sl{Z>pf*7f-^R?+*pe{>R%J?(-s;^TrpyMO8?^}L1o6P}svF9~ zG1HNOqF2;(;%@RjwmR<&7)WG?(eJgMy8Pnyc-V<(IwhnZXOu}z^>$K5Ax8p!43~&L zehFWK@Qw4-(Wd9jRcWFF-*_$wzglOXrDqhSvXPWC-L(&-$j-vWNd<>IqfIQP&a8Oo zSYYEMY{0YHH`%xBs-f7v7X}w(OesKcRS#h%B`bJb=NeSJ>vK8P{)Wdu#cP!zkn(ca z?0UE2vs>MZCk&&BdqauH-0wbOfN?+Df-^4(f~BQfvRlv8dHgwXsl+Lkd!E?(iQA1v zNry+;oAROKaA@sz9jW^eFU68o7K@G1Om^r@pE2S;WXPsWUi>yE;PYg;kmquk#tb>_ zW_8#TrBL^GLVPKJBLa_YmK7+n25#(5m{I#S0m?owR1O@W`YTB!|Dw{`1Y{%wK(kvB z4%a~!^8zTLcl8D%YR*Fl)qDNWyHZa5UC42B_fr6W@r57#gppsLo>#oE>hMg# zi3B%rT93-QHGLg*xw)&u-o{iOFDfQ$g*T8Y93KU?U8y+fZ8_Yx$CMmR-UF`sX}-hw zsFvlbXAPQr^(H>JMB_pBuvRKmsR~}Y{PA+V@N2r8v85)hkd}~7a>`u0i@K{Ou8*s}ESxCJf`)nTv4&Vn$L_E9aq2ximqyA%Env01v4 z_?km*M>_2>QBNcCQPr1dk^!GuxSgZCP&BFy8_xP~e-nj5hnlNF2EJCb)hm0)oo`c- z8U*WR;8>$^2*=uVCHzhN7|sfYQI-xCpO_v5&|6mfwpm8G5;c;lX1zllU?=&1mI|)s z&jzgDpiF|YZjv$4ESnsKFQEd3E^?&nc8QJTQ5eE2;Ldfm)YL6tl{+rjwGVo&k52le zZ3bj0UGEAli&K%Rzx?}A=0=h@e>!cfSIKg2YQokaS_2`(WyUhs@l;QGReY1iyeGu5 z#|i0)_^adjLN*S^BzjxKeQ!;+u+he3Kc1JB8sK_*#2W@3JAL|l><8lu5dQSfWkCYfKsqNm3K9*Krhh9+C-Bdq7 zeu1%!AM&ugnga+mAJv*F9t^98dmz%fNId*dn!fzHxvu_poQv^JJ0b)=Z;MRPsevV= WZsm&(_M-DElKo;>EgapZ!~X&Z6SK?! literal 1503 zcmcIky>8nu5S|$z?{K3G%Z@xJDbT;cKmiXO4G%PRcGya!Kv7QIB=6HcL8hYZmIvtC z*XZ1%NZFKKAVtv*0z~q7{O-H&zKV#tV$Ow|EwT zu~$Z4gCaVo?rhfB+3JOER9?Tn5m;HNRRH-nrMcqXZflF>m^+mTU2S82QjaK&g%kE* z2$R(7ZRDelxoXSl$YOh{oEG*(g%+*RCOfL4cKsuQT&V_aV^mzs+(QidJi=tK)EoSt zuo&wUN}7t483Fr~4*70G_jjFZ9U*iGMlkVRa=W8ZEABvw({sNsou70Q9s=Ff5F5?& z)S}^58<62A8Qeyc2dfDW1W$SR{P59H9{j7F+1~JZX9+&C07-M%H?Y0SLJ(_}IOCDPsb&3(#EWO~{uf`I*!=(i diff --git a/group16/313001956/src/com/coding/basic/LinkedList.java b/group16/313001956/src/com/coding/basic/LinkedList.java index de886c9084ccf244f58d8a1cf62b65ce290385c0..483ca7ac44abbf2626e0cf434ab6ba5bc9333799 100644 GIT binary patch literal 7771 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 O(X<<`@1Nf9|NjF_*t0kQ literal 2332 zcmcguOK#gR5M47s?l8zoL24six6YzKTLdubMNdFW6Pt}p3KIQklN_e#IdY5Mq1Py9 z_=zkz1_T7&QRIByy!ok;`Mq2qB(4qAZ+^bg8t3M*TvzD}vz{li6i3^5ji<#~Y&x zkVTQr=07mEU|32BcQuub&CDgaIIKbrl`e4i4m#TE4l;g$k8ll-k6sLJ7+>%p?6Njn z(71(LGBR7++1)3z)(b>h{=jVTaeqS&Of*}OirqE$B0lhBEXwKiUJ)$S` zDuS-Zg|reTU?>*x1Xwm0$Pj|L)b4eGmd^8^49DXqBcv0gaI1-V=h&fcdvV|NvhPU5 zTa7zQN@F@O2I0@%5@~v5g7?0TVu7bLrZ`%u`q zyk7#bSHGy*b!J4=DuOp^i#IBFLc_sx4-P2x7$*;)6NKrYb$XxZ5A(y<$I!;-A{Y>I zh|<@;&+lt_JK9r;%twv_fs~&rZ&JQ#PjKw{~Yozu56)lOx;N!GSYJTPj?yT=Yw$oXHgdO&moF eAkH{dRM&W_vW{_<^?W5x!UAL}oj8%fTK@qj;+JOt 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/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/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/group16/420355244/Homework3/src/com/coding/basic/LinkedList.java b/group16/420355244/Homework3/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..4fdb03db8a --- /dev/null +++ b/group16/420355244/Homework3/src/com/coding/basic/LinkedList.java @@ -0,0 +1,124 @@ +package com.coding.basic; + + + +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/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..c0cce5af0a 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,26 @@ 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; + } @@ -169,9 +218,44 @@ public void remove(int i, int length) { * @param list */ public int[] getElements(LinkedList list) { - return null; + if (size() == 0) { + return new int[0]; + } + Iterator iterator = list.iterator(); + Node fromNode = iterator().nextNode(); + int fromIndex = 0; + + int[] retArray = new int[list.size()]; + int retIndex = 0; + while (iterator.hasNext()) { + int index = (int) iterator.next(); + Node node = node(fromNode, fromIndex, index); + fromIndex = index; + fromNode = node; + if (node == null) { + return retArray; + } else { + retArray[retIndex++] = (int)node.data; + } + } + return retArray; + } + + private Node node(Node fromNode, int fromIndex, int index) { + Node next = fromNode; + int nextIndex = fromIndex; + while (next != null && nextIndex < index) { + next = next.next; + nextIndex++; + } + if (nextIndex == index) { + return next; + } else { + return null; + } } + /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 从当前链表中中删除在listB中出现的元素 @@ -229,6 +313,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 +334,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/api/ArrayListTest.java b/group17/1204187480/code/homework/basic/src/test/java/com/coding/api/ArrayListTest.java deleted file mode 100644 index 95f0085b66..0000000000 --- a/group17/1204187480/code/homework/basic/src/test/java/com/coding/api/ArrayListTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.coding.api; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Created by luoziyihao on 2/25/17. - */ -public class ArrayListTest { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testAdd(){ - List list = new ArrayList(Arrays.asList(0, 1, 2, 3)); - logger.info("list={}", list); - list.add(5, 2); - logger.info("list={}", list); - } -} 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..0424c2945e 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,181 @@ package com.coding.basic; +import org.junit.Assert; import org.junit.Test; -import static org.junit.Assert.*; +import java.util.Arrays; /** * 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) { + return createAndFillLinkedList(1, length); + } + + private LinkedList createAndFillLinkedList(int start, int length) { + LinkedList linkedList = new LinkedList(); + for (int i = start; 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 { + LinkedList listA= createAndFillLinkedList(0,8); + LinkedList listB = createAndFillLinkedList(4, 4); + Assert.assertEquals("[4,5,6,7]", Arrays.toString(listA.getElements(listB))); + + } + + @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 +186,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/group17/1204187480/code/homework/parent/pom.xml b/group17/1204187480/code/homework/parent/pom.xml index 7af48c6fed..ace9bf9cc5 100644 --- a/group17/1204187480/code/homework/parent/pom.xml +++ b/group17/1204187480/code/homework/parent/pom.xml @@ -92,4 +92,13 @@ + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.19.1 + + + \ No newline at end of file diff --git a/group17/1264835468/.gitignore b/group17/1264835468/.gitignore index 71f96b185c..1517b9e684 100644 --- a/group17/1264835468/.gitignore +++ b/group17/1264835468/.gitignore @@ -1,5 +1,7 @@ -/bin/ +/bin/ .classpath .project -.gitignore \ No newline at end of file +.gitignore +/.idea/ +.iml diff --git a/group17/1264835468/src/assignment2_26/ArrayUtil.java b/group17/1264835468/src/assignment0226/ArrayUtil.java similarity index 95% rename from group17/1264835468/src/assignment2_26/ArrayUtil.java rename to group17/1264835468/src/assignment0226/ArrayUtil.java index 89d2a0db29..f8be858ad9 100644 --- a/group17/1264835468/src/assignment2_26/ArrayUtil.java +++ b/group17/1264835468/src/assignment0226/ArrayUtil.java @@ -1,183 +1,183 @@ -package assignment2_26; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.TreeSet; - -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 = origin.length / 2; - for (int i = 0; i < mid; i++) { - int temp = origin[i]; - int reversePosition = origin.length - 1; - origin[i] = origin[reversePosition]; - origin[reversePosition] = 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 count = 0; - for (int i : oldArray) { - if (i != 0) - count++; - } - int[] newArray = new int[count]; - int currentPos = 0; - for (int i = 0; i < oldArray.length; i++) { - if (oldArray[i] != 0) - newArray[currentPos++] = 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 static int[] merge(int[] array1, int[] array2) { - TreeSet set = new TreeSet<>(); - for (Integer integer : array1) { - set.add(integer); - } - for (Integer integer : array2) { - set.add(integer); - } - int[] result = new int[set.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = set.pollFirst(); - } - return result; - } - - /** - * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size - * 注意,老数组的元素在新数组中需要保持 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 - * [2,3,6,0,0,0] - * - * @param oldArray - * @param size - * @return - */ - public static int[] grow(int[] oldArray, int size) { - return Arrays.copyOf(oldArray, size); - } - - /** - * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 例如, max = 15 , - * 则返回的数组应该为 [1,1,2,3,5,8,13] max = 1, 则返回空数组 [] - * - * @param max - * @return - */ - public static int[] fibonacci(int max) { - if (max <= 1) - return new int[0]; - List fList = new ArrayList<>(); - fList.add(1); - fList.add(1); - int last = fList.size() - 1; - while (fList.get(last) < max) { - fList.add(fList.get(last) + fList.get(last - 1)); - last++; - } - int[] result = new int[fList.size() - 1]; - for (int i = 0; i < result.length; i++) { - result[i] = fList.get(i); - } - return result; - } - - /** - * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * - * @param max - * @return - */ - public static int[] getPrimes(int max) { - boolean[] isPrime = new boolean[max]; - List primes = new ArrayList<>(); - for (int i = 0; i < isPrime.length; i++) { - isPrime[i] = true; - } - for (int i = 2; i * i < max; i++) { - for (int j = i; i * j < max; j++) - isPrime[i * j] = false; - } - for (int i = 2; i < isPrime.length; i++) { - if (isPrime[i]) - primes.add(i); - } - int[] result = new int[primes.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = primes.get(i); - } - return result; - } - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * - * @param max - * @return - */ - public static int[] getPerfectNumbers(int max) { - int sum = 0; - ArrayList perfectNumbers = new ArrayList<>(); - for (int i = 1; i < max; i++) { - for (int j = 1; j < i; j++) { - if (i % j == 0) { - sum += j; - } - } - if (sum == i) - perfectNumbers.add(i); - sum = 0; - } - - int[] result = new int[perfectNumbers.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = perfectNumbers.get(i); - } - return result; - } - - /** - * 用seperator 把数组 array给连接起来 例如array= [3,8,9], seperator = "-" 则返回值为"3-8-9" - * - * @param array - * @param s - * @return - */ - public static String join(int[] array, String seperator) { - StringBuilder stringBuilder = new StringBuilder(); - for (int i : array) { - stringBuilder.append(i + seperator); - } - stringBuilder.delete(stringBuilder.length() - seperator.length(), stringBuilder.length()); - - return stringBuilder.toString(); - } - -} +package assignment0226; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.TreeSet; + +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 = origin.length / 2; + for (int i = 0; i < mid; i++) { + int temp = origin[i]; + int reversePosition = origin.length - 1; + origin[i] = origin[reversePosition]; + origin[reversePosition] = 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 count = 0; + + for (int i : oldArray) { + if (i != 0) + count++; + } + int[] newArray = new int[count]; + int currentPos = 0; + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] != 0) + newArray[currentPos++] = 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 static int[] merge(int[] array1, int[] array2) { + TreeSet set = new TreeSet<>(); + for (Integer integer : array1) { + set.add(integer); + } + for (Integer integer : array2) { + set.add(integer); + } + int[] result = new int[set.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = set.pollFirst(); + } + return result; + } + + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * + * @param oldArray + * @param size + * @return + */ + public static int[] grow(int[] oldArray, int size) { + return Arrays.copyOf(oldArray, size); + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 例如, max = 15 , + * 则返回的数组应该为 [1,1,2,3,5,8,13] max = 1, 则返回空数组 [] + * + * @param max + * @return + */ + public static int[] fibonacci(int max) { + if (max <= 1) + return new int[0]; + List fList = new ArrayList<>(); + fList.add(1); + fList.add(1); + int last = fList.size() - 1; + while (fList.get(last) < max) { + fList.add(fList.get(last) + fList.get(last - 1)); + last++; + } + int[] result = new int[fList.size() - 1]; + for (int i = 0; i < result.length; i++) { + result[i] = fList.get(i); + } + return result; + } + + /** + * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * + * @param max + * @return + */ + public static int[] getPrimes(int max) { + boolean[] isPrime = new boolean[max]; + List primes = new ArrayList<>(); + for (int i = 0; i < isPrime.length; i++) { + isPrime[i] = true; + } + for (int i = 2; i * i < max; i++) { + for (int j = i; i * j < max; j++) + isPrime[i * j] = false; + } + for (int i = 2; i < isPrime.length; i++) { + if (isPrime[i]) + primes.add(i); + } + int[] result = new int[primes.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = primes.get(i); + } + return result; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * + * @param max + * @return + */ + public static int[] getPerfectNumbers(int max) { + int sum = 0; + ArrayList perfectNumbers = new ArrayList<>(); + for (int i = 1; i < max; i++) { + for (int j = 1; j < i; j++) { + if (i % j == 0) { + sum += j; + } + } + if (sum == i) + perfectNumbers.add(i); + sum = 0; + } + + int[] result = new int[perfectNumbers.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = perfectNumbers.get(i); + } + return result; + } + + /** + * 用seperator 把数组 array给连接起来 例如array= [3,8,9], seperator = "-" 则返回值为"3-8-9" + * + * @param array + * @param seperator + * @return + */ + public static String join(int[] array, String seperator) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i : array) { + stringBuilder.append(i + seperator); + } + stringBuilder.delete(stringBuilder.length() - seperator.length(), stringBuilder.length()); + + return stringBuilder.toString(); + } +} diff --git a/group17/1264835468/src/assignment2_26/ArrayUtilTest.java b/group17/1264835468/src/assignment0226/ArrayUtilTest.java similarity index 95% rename from group17/1264835468/src/assignment2_26/ArrayUtilTest.java rename to group17/1264835468/src/assignment0226/ArrayUtilTest.java index 753c026796..1ccd845e1c 100644 --- a/group17/1264835468/src/assignment2_26/ArrayUtilTest.java +++ b/group17/1264835468/src/assignment0226/ArrayUtilTest.java @@ -1,100 +1,100 @@ -package assignment2_26; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class ArrayUtilTest { - - @Test - public void testReverseArray() { - int[] array = new int[] {}; - ArrayUtil.reverseArray(array); - assertArrayEquals(new int[] {}, array); - - array = new int[] { 1 }; - ArrayUtil.reverseArray(array); - assertArrayEquals(new int[] { 1 }, array); - - array = new int[] { 1, 2, 3 }; - ArrayUtil.reverseArray(array); - assertArrayEquals(new int[] { 3, 2, 1 }, array); - } - - @Test - public void testRemoveZero() { - int[] array = new int[] {}; - assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array)); - - array = new int[] { 0 }; - assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array)); - - array = new int[] { 1 }; - assertArrayEquals(new int[] { 1 }, ArrayUtil.removeZero(array)); - - array = new int[] { 1, 2, 0, 0, 3 }; - assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array)); - - array = new int[] { 1, 2, 3 }; - assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array)); - } - - @Test - public void testMerge() { - int[] array1 = { 3, 5, 7, 8 }; - int[] array2 = { 4, 5, 6, 7 }; - assertArrayEquals(new int[] { 3, 4, 5, 6, 7, 8 }, ArrayUtil.merge(array1, array2)); - } - - @Test - public void testGrow() { - int[] array = { 3, 5, 7 }; - assertArrayEquals(new int[] { 3, 5, 7, 0, 0 }, ArrayUtil.grow(array, 5)); - assertArrayEquals(new int[] { 3, 5, 7 }, ArrayUtil.grow(array, 3)); - } - - @Test - public void testFibonacci() { - assertArrayEquals(new int[] {}, ArrayUtil.fibonacci(1)); - - assertArrayEquals(new int[] { 1, 1 }, ArrayUtil.fibonacci(2)); - - assertArrayEquals(new int[] { 1, 1, 2, 3, 5, 8, 13 }, ArrayUtil.fibonacci(15)); - } - - @Test - public void testGetPrimes() { - assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(1)); - - assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(2)); - - assertArrayEquals(new int[] { 2 }, ArrayUtil.getPrimes(3)); - - assertArrayEquals(new int[] { 2, 3, 5, 7, 11, 13, 17, 19 }, ArrayUtil.getPrimes(20)); - } - - @Test - public void testGetPerfectNumbers() { - assertArrayEquals(new int[] { 6 }, ArrayUtil.getPerfectNumbers(10)); - - assertArrayEquals(new int[] { 6, 28 }, ArrayUtil.getPerfectNumbers(100)); - - assertArrayEquals(new int[] { 6, 28, 496 }, ArrayUtil.getPerfectNumbers(1000)); - - assertArrayEquals(new int[] { 6, 28, 496, 8128 }, ArrayUtil.getPerfectNumbers(10000)); - - } - - @Test - public void testJoin() { - assertEquals("3-4-5", ArrayUtil.join(new int[] { 3, 4, 5 }, "-")); - - assertEquals("345", ArrayUtil.join(new int[] { 3, 4, 5 }, "")); - - assertEquals("3", ArrayUtil.join(new int[] { 3 }, "")); - - assertEquals("3--4--5", ArrayUtil.join(new int[] { 3, 4, 5 }, "--")); - } - -} +package assignment0226; + +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class ArrayUtilTest { + + @Test + public void testReverseArray() { + int[] array = new int[] {}; + ArrayUtil.reverseArray(array); + assertArrayEquals(new int[] {}, array); + + array = new int[] { 1 }; + ArrayUtil.reverseArray(array); + assertArrayEquals(new int[] { 1 }, array); + + array = new int[] { 1, 2, 3 }; + ArrayUtil.reverseArray(array); + assertArrayEquals(new int[] { 3, 2, 1 }, array); + } + + @Test + public void testRemoveZero() { + int[] array = new int[] {}; + assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array)); + + array = new int[] { 0 }; + assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array)); + + array = new int[] { 1 }; + assertArrayEquals(new int[] { 1 }, ArrayUtil.removeZero(array)); + + array = new int[] { 1, 2, 0, 0, 3 }; + assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array)); + + array = new int[] { 1, 2, 3 }; + assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array)); + } + + @Test + public void testMerge() { + int[] array1 = { 3, 5, 7, 8 }; + int[] array2 = { 4, 5, 6, 7 }; + assertArrayEquals(new int[] { 3, 4, 5, 6, 7, 8 }, ArrayUtil.merge(array1, array2)); + } + + @Test + public void testGrow() { + int[] array = { 3, 5, 7 }; + assertArrayEquals(new int[] { 3, 5, 7, 0, 0 }, ArrayUtil.grow(array, 5)); + assertArrayEquals(new int[] { 3, 5, 7 }, ArrayUtil.grow(array, 3)); + } + + @Test + public void testFibonacci() { + assertArrayEquals(new int[] {}, ArrayUtil.fibonacci(1)); + + assertArrayEquals(new int[] { 1, 1 }, ArrayUtil.fibonacci(2)); + + assertArrayEquals(new int[] { 1, 1, 2, 3, 5, 8, 13 }, ArrayUtil.fibonacci(15)); + } + + @Test + public void testGetPrimes() { + assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(1)); + + assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(2)); + + assertArrayEquals(new int[] { 2 }, ArrayUtil.getPrimes(3)); + + assertArrayEquals(new int[] { 2, 3, 5, 7, 11, 13, 17, 19 }, ArrayUtil.getPrimes(20)); + } + + @Test + public void testGetPerfectNumbers() { + assertArrayEquals(new int[] { 6 }, ArrayUtil.getPerfectNumbers(10)); + + assertArrayEquals(new int[] { 6, 28 }, ArrayUtil.getPerfectNumbers(100)); + + assertArrayEquals(new int[] { 6, 28, 496 }, ArrayUtil.getPerfectNumbers(1000)); + + assertArrayEquals(new int[] { 6, 28, 496, 8128 }, ArrayUtil.getPerfectNumbers(10000)); + + } + + @Test + public void testJoin() { + assertEquals("3-4-5", ArrayUtil.join(new int[] { 3, 4, 5 }, "-")); + + assertEquals("345", ArrayUtil.join(new int[] { 3, 4, 5 }, "")); + + assertEquals("3", ArrayUtil.join(new int[] { 3 }, "")); + + assertEquals("3--4--5", ArrayUtil.join(new int[] { 3, 4, 5 }, "--")); + } + +} diff --git a/group17/1264835468/src/assignment0226/LoginAction.java b/group17/1264835468/src/assignment0226/LoginAction.java new file mode 100644 index 0000000000..652b5359ac --- /dev/null +++ b/group17/1264835468/src/assignment0226/LoginAction.java @@ -0,0 +1,42 @@ +package assignment0226; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * + * @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/group17/1264835468/src/assignment2_26/Struts.java b/group17/1264835468/src/assignment0226/Struts.java similarity index 96% rename from group17/1264835468/src/assignment2_26/Struts.java rename to group17/1264835468/src/assignment0226/Struts.java index ad704e0433..457b6ad953 100644 --- a/group17/1264835468/src/assignment2_26/Struts.java +++ b/group17/1264835468/src/assignment0226/Struts.java @@ -1,99 +1,99 @@ -package assignment2_26; - -import java.io.File; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -public class Struts { - - private static File configFile = new File("./src/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字段中。 - - */ - // 0 - XmlParser phraser = new XmlParser(configFile); - String className = phraser.getClassNameByActionName(actionName); - View view = new View(); - try { - // 1 - Class actionClass = Class.forName(className); - Constructor constructor = actionClass.getConstructor(); - Object instance = constructor.newInstance(); - invokeSetters(actionClass, instance, parameters); - - // 2 - String result = invokeExecute(actionClass, instance); - - // 3 - Map getterResult = invokeGetters(actionClass, instance); - view.setParameters(getterResult); - - // 4 - String resultJsp = phraser.getResultJsp(actionName, result); - view.setJsp(resultJsp); - - } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException - | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - e.printStackTrace(); - } - - return view; - } - - private static Map invokeGetters(Class actionClass, Object instance) - throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Map result = new HashMap<>(); - for (Method method : actionClass.getDeclaredMethods()) { - if (method.getName().matches("get.*")) { - String fieldName = method.getName().substring(3).toLowerCase(); - String value = (String) (method.invoke(instance)); - result.put(fieldName, value); - } - } - return result; - } - - private static String invokeExecute(Class actionClass, Object instance) throws NoSuchMethodException, - SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Method method = actionClass.getDeclaredMethod("execute"); - return (String) method.invoke(instance); - } - - private static void invokeSetters(Class actionClass, Object instance, Map parameters) - throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException { - for (String fieldName : parameters.keySet()) { - invokeSetter(actionClass, instance, fieldName, parameters.get(fieldName)); - } - } - - private static void invokeSetter(Class actionClass, Object instance, String fieldName, String value) - throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, - InvocationTargetException { - String setterName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); - Method setter = actionClass.getDeclaredMethod(setterName, String.class); - setter.invoke(instance, value); - } -} +package assignment0226; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class Struts { + + private static File configFile = new File("./src/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字段中。 + + */ + // 0 + XmlParser phraser = new XmlParser(configFile); + String className = phraser.getClassNameByActionName(actionName); + View view = new View(); + try { + // 1 + Class actionClass = Class.forName(className); + Constructor constructor = actionClass.getConstructor(); + Object instance = constructor.newInstance(); + invokeSetters(actionClass, instance, parameters); + + // 2 + String result = invokeExecute(actionClass, instance); + + // 3 + Map getterResult = invokeGetters(actionClass, instance); + view.setParameters(getterResult); + + // 4 + String resultJsp = phraser.getResultJsp(actionName, result); + view.setJsp(resultJsp); + + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException + | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + + return view; + } + + private static Map invokeGetters(Class actionClass, Object instance) + throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Map result = new HashMap<>(); + for (Method method : actionClass.getDeclaredMethods()) { + if (method.getName().matches("get.*")) { + String fieldName = method.getName().substring(3).toLowerCase(); + String value = (String) (method.invoke(instance)); + result.put(fieldName, value); + } + } + return result; + } + + private static String invokeExecute(Class actionClass, Object instance) throws NoSuchMethodException, + SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method method = actionClass.getDeclaredMethod("execute"); + return (String) method.invoke(instance); + } + + private static void invokeSetters(Class actionClass, Object instance, Map parameters) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException { + for (String fieldName : parameters.keySet()) { + invokeSetter(actionClass, instance, fieldName, parameters.get(fieldName)); + } + } + + private static void invokeSetter(Class actionClass, Object instance, String fieldName, String value) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException { + String setterName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); + Method setter = actionClass.getDeclaredMethod(setterName, String.class); + setter.invoke(instance, value); + } +} diff --git a/group17/1264835468/src/assignment0226/StrutsTest.java b/group17/1264835468/src/assignment0226/StrutsTest.java new file mode 100644 index 0000000000..1e677c38b3 --- /dev/null +++ b/group17/1264835468/src/assignment0226/StrutsTest.java @@ -0,0 +1,38 @@ +package assignment0226; + +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/group17/1264835468/src/assignment0226/View.java b/group17/1264835468/src/assignment0226/View.java new file mode 100644 index 0000000000..3bd518e451 --- /dev/null +++ b/group17/1264835468/src/assignment0226/View.java @@ -0,0 +1,26 @@ +package assignment0226; + +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/group17/1264835468/src/assignment2_26/XmlParser.java b/group17/1264835468/src/assignment0226/XmlParser.java similarity index 95% rename from group17/1264835468/src/assignment2_26/XmlParser.java rename to group17/1264835468/src/assignment0226/XmlParser.java index aa34335cb6..4969951082 100644 --- a/group17/1264835468/src/assignment2_26/XmlParser.java +++ b/group17/1264835468/src/assignment0226/XmlParser.java @@ -1,72 +1,72 @@ -package assignment2_26; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -public class XmlParser { - private File file; - List actionElements; - - public XmlParser(File file) { - this.file = file; - actionElements = new ArrayList<>(); - getActionsFromFile(); - } - - public String getClassNameByActionName(String actionName) { - Element action = getElementByActionName(actionName); - return action.getAttribute("class"); - } - - public String getResultJsp(String actionName, String resultName) { - Element action = getElementByActionName(actionName); - NodeList results = action.getChildNodes(); - for (int i = 0; i < results.getLength(); i++) { - Node child = results.item(i); - if (child instanceof Element) { - Element result = (Element) child; - if (result.getAttribute("name").equals(resultName)) - return result.getTextContent(); - } - } - throw new RuntimeException("not found result named:" + resultName); - } - - private Element getElementByActionName(String actionName) { - for (Element element : actionElements) { - if (element.getAttribute("name").equals(actionName)) { - return element; - } - } - throw new RuntimeException("no such element named " + actionName); - } - - private void getActionsFromFile() { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - try { - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.parse(file); - Element root = document.getDocumentElement(); - NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - if (child instanceof Element) - actionElements.add((Element) child); - } - } catch (ParserConfigurationException | SAXException | IOException e) { - e.printStackTrace(); - } - } -} +package assignment0226; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +public class XmlParser { + private File file; + List actionElements; + + public XmlParser(File file) { + this.file = file; + actionElements = new ArrayList<>(); + getActionsFromFile(); + } + + public String getClassNameByActionName(String actionName) { + Element action = getElementByActionName(actionName); + return action.getAttribute("class"); + } + + public String getResultJsp(String actionName, String resultName) { + Element action = getElementByActionName(actionName); + NodeList results = action.getChildNodes(); + for (int i = 0; i < results.getLength(); i++) { + Node child = results.item(i); + if (child instanceof Element) { + Element result = (Element) child; + if (result.getAttribute("name").equals(resultName)) + return result.getTextContent(); + } + } + throw new RuntimeException("not found result named:" + resultName); + } + + private Element getElementByActionName(String actionName) { + for (Element element : actionElements) { + if (element.getAttribute("name").equals(actionName)) { + return element; + } + } + throw new RuntimeException("no such element named " + actionName); + } + + private void getActionsFromFile() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(file); + Element root = document.getDocumentElement(); + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child instanceof Element) + actionElements.add((Element) child); + } + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java b/group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..a5add91113 --- /dev/null +++ b/group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java @@ -0,0 +1,59 @@ +package assignment0326.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/3/30. + */ +public class ClassFileLoader { + + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + String path = className.replace(".", File.separator); + File classFile=null; + for (String p: clzPaths) { + classFile=new File(p+File.separator+path+".class"); + if(classFile.exists()) + break; + } + if(classFile==null) + throw new RuntimeException("no such class file"); + + byte[] bytes=new byte[(int)classFile.length()]; + try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(classFile))){ + bufferedInputStream.read(bytes, 0, bytes.length); + + } catch (IOException e) { + e.printStackTrace(); + } + return bytes; + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuilder stringBuilder=new StringBuilder(); + for (int i = 0; i strings=new ArrayList<>(); + for (int i = 0; i <10; i++) { + strings.add(String.valueOf(new Random().nextInt(3000))); + } + System.out.println(strings); + System.out.println(strings.stream().map(s-> s.charAt(0)).sorted().distinct().limit(5).collect(Collectors.toList())); + } + + public int findMinDifference(List timePoints) { + List list=new ArrayList<>(); + + for (String s:timePoints) { + list.add(parse(s)); + } + Collections.sort(list); + int min=Integer.MAX_VALUE; + for (int i = 0; i < list.size()-1; i++) { + min=Math.min(min,Math.min(Math.abs(list.get(i+1)-list.get(i)),24*60-Math.abs(list.get(i+1)-list.get(i)))); + } + return min; + } + + private Integer parse(String s) { + return Integer.parseInt(s.substring(0, 2)) * 60 + Integer.parseInt(s.substring(3, 5)); + } +} diff --git a/group17/1264835468/src/assignment0326/lru/LRUPageFrame.java b/group17/1264835468/src/assignment0326/lru/LRUPageFrame.java new file mode 100644 index 0000000000..fd2f2693c4 --- /dev/null +++ b/group17/1264835468/src/assignment0326/lru/LRUPageFrame.java @@ -0,0 +1,128 @@ +package assignment0326.lru; + +/** + * 用双向链表实现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 Node first;// 链表头 + private Node last;// 链表尾 + + private int size; + public LRUPageFrame(int capacity) { + if(capacity<=0) + throw new IllegalArgumentException("capacity:"+capacity+" <= 0"); + this.capacity = capacity; + first=null; + last=null; + size=0; + + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + Node target=search(pageNum); + if (target == null) { + target=new Node(pageNum); + linkFirst(target); + }else{ + moveToFirst(target); + } + if(size>capacity){ + removeLast(); + } + } + + private Node search(int pageNum) { + Node f=first; + while (f!=null){ + if (f.pageNum == pageNum) { + return f; + } + f=f.next; + } + return null; + } + + private void linkFirst(Node target) { + if(first==null){ + first=last=target; + }else { + target.next = first; + first.prev = target; + first = target; + } + size++; + } + + private void moveToFirst(Node target) { + if(target==first){ + return; + } + + Node prevOfTarget=target.prev; + prevOfTarget.next=target.next; + + if(target==last) { + last=prevOfTarget; + }else { + target.next.prev = prevOfTarget; + } + + target.next=first; + first.prev=target; + first=target; + + } + + private void removeLast() { + Node prevOfLast=last.prev; + last.prev=null; + last=prevOfLast; + + if(last==null){ + first=null; + }else { + last.next=null; + } + 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(); + } + +} \ No newline at end of file diff --git a/group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java b/group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java new file mode 100644 index 0000000000..7a54f54c8d --- /dev/null +++ b/group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java @@ -0,0 +1,34 @@ +package assignment0326.lru; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by Administrator on 2017/3/29. + */ + + +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/group17/1264835468/src/struts.xml b/group17/1264835468/src/struts.xml index ad43b47967..9ba23d1e24 100644 --- a/group17/1264835468/src/struts.xml +++ b/group17/1264835468/src/struts.xml @@ -1,6 +1,6 @@ - + /jsp/homepage.jsp /jsp/showLogin.jsp diff --git a/group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java b/group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..6d669e294f --- /dev/null +++ b/group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,86 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + String classPath = convertToFilePath(className); + File targetFile = null; + for(int i = 0; i< clzPaths.size(); i++){ + String fullPath = clzPaths.get(i)+File.separator+classPath; + System.out.println("path: " + fullPath); + File temp = new File(fullPath); + if(temp.exists()) { + targetFile = temp; + break; + } + } + + if(targetFile != null){ + System.out.println("targetFile: " + targetFile.getAbsolutePath()); + } + long fileLength = targetFile.length(); + System.out.println("File length: " + fileLength); + byte[] byteArray = new byte[(int)fileLength]; + FileInputStream is = null; + try { + is = new FileInputStream(targetFile); + is.read(byteArray); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }finally{ + if(is != null){ + try { + is.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + + return byteArray; + + + } + + private String convertToFilePath(String className){ + return className.replaceAll("\\.", File.separator) + ".class"; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + for(String item : clzPaths){ + sb.append(item + ";"); + } + return sb.substring(0, sb.length()-1); + } + + + + + +} \ No newline at end of file diff --git a/group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..4df3f4b529 --- /dev/null +++ b/group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,103 @@ +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"; + static String path3 = "/Users/erlisuo/Documents/workspace/codeRising2017working/1282579502/bin"; + + + @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); + loader.addClassPath(path2); + loader.addClassPath(path3); + 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); + loader.addClassPath(path3); + 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); + } + + + @Test + public void testToHexString(){ + byte b1 = 'a'; + byte b2 = 'b'; + System.out.println("Binary: " + Integer.toBinaryString(b1) + " decimal: " + Integer.toString(b1) + " hex: " + Integer.toHexString(b1)); + System.out.println("Binary: " + Integer.toBinaryString(b2) + " decimal: " + Integer.toString(b2) + " hex: " + Integer.toHexString(b2)); + + byte[] bArray = new byte[]{b1, b2}; + System.out.println(byteToHexString(bArray)); + } + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i keyHash; + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + this.count = 0; + keyHash = new HashMap(); + first = new Node(); + first.pageNum = -99; + last = new Node(); + last.pageNum = -99; + first.next = last; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + Node targetPageNode = keyHash.get(new Integer(pageNum)); + + if(targetPageNode == null){ + targetPageNode = new Node(); + targetPageNode.pageNum = pageNum; + addNewPage(targetPageNode); + } + else{ + moveToTop(targetPageNode); + } + + } + /* + * null - first - f1 - f2 -f3 + */ + private void moveToTop(Node targetNode){ + if(targetNode != first.next){ + targetNode.prev.next = targetNode.next; + if(targetNode.next != null){ + targetNode.next.prev = targetNode.prev; + } + + targetNode.next = first.next; + if(first.next != null){ + first.next.prev = targetNode; + } + + first.next = targetNode; + targetNode.prev = first; + } + } + + private void addNewPage(Node targetPageNode){ + //first.next ?= null + // + targetPageNode.next = first.next; + if(first.next != null){ + first.next.prev = targetPageNode; + } + + first.next = targetPageNode; + targetPageNode.prev = first; + + keyHash.put(targetPageNode.pageNum, targetPageNode); + count++; + if(count > capacity){ + popOutLast(); + } + } + /* + * t3 - t2 - t1 - last - null + */ + private void popOutLast(){ + Node tailNode = last.prev; //t1 + if(tailNode != null){ + Node preTailNode = tailNode.prev; //t2 + if(preTailNode != null){ + keyHash.remove(preTailNode.pageNum); + preTailNode.next = last; //t2 -> last + last.prev = preTailNode; + count --; + } + } + } + public void printList(){ + int tmpcount = 0; + Node node = first.next; + while(node != last && tmpcount++<20){ + System.out.println("current: "+node.pageNum+ " parent: " + node.prev.pageNum); + node = node.next; + } + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first.next; + while(node != null){ + if(node == last) break; + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + + } + + String returnStr = null; + if(buffer.charAt(buffer.length() -1 ) == ','){ + returnStr = buffer.substring(0, buffer.length() -1); + }else{ + returnStr = buffer.toString(); + } + return returnStr; + } + +} \ No newline at end of file diff --git a/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..0bfbe14fd0 --- /dev/null +++ b/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,55 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + +// @Test +// public void toStringTest(){ +// LRUPageFrame frame = new LRUPageFrame(3); +// frame.access(7); +// frame.access(0); +// frame.access(1); +// System.out.println("array: " + frame.toString()); +// frame.access(2); +// System.out.println("array: " + frame.toString()); +// +// frame.access(0); +// System.out.println("array: " + frame.toString()); +// frame.access(0); +// System.out.println("array: " + frame.toString()); +// frame.access(3); +// System.out.println("array: " + frame.toString()); +// +// frame.access(0); +// System.out.println("array: " + frame.toString()); +// +// frame.access(4); +// System.out.println("array: " + frame.toString()); +// } + + @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/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..638cf181ae --- /dev/null +++ b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,126 @@ +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 int currentSize; + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + currentSize = 0; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + + // 判断缓存是否命中 + Node n = find(pageNum); + if(n != null){ + // 命中,则把节点提到表头 + moveNodeToHead(n); + }else{ + // 若未命中,新增节点放到表头,如果链表长度超过capacity,移除链表尾部节点 + n = new Node(); + n.pageNum = pageNum; + + if(currentSize >= capacity){ + removeLast(); + } + addNodeToHead(n); + } + } + + + + private void addNodeToHead(Node n) { + if(first == null){ + first = n; + last = n; + }else{ + n.next = first; + first.prev = n; + first = n; + } + currentSize++; + } + + private void removeLast() { + Node prevN = last.prev; + prevN.next = null; + last.prev = null; + last = prevN; + currentSize--; + } + + private void moveNodeToHead(Node n) { + if(n == first){ + return ; + }else if(n == last){ + Node preN = n.prev; + preN.next = null; + last.prev = null; + last = preN; + }else{ + // 中间节点 + Node preN = n.prev; + Node nextN = n.next; + preN.next = nextN; + nextN.prev = preN; + } + n.prev = null; + n.next = first; + first.prev = n; + first = n; + } + + private Node find(int pageNum) { + Node n = first; + while(n != null){ + if(n.pageNum == pageNum){ + return n; + } + n = n.next; + } + 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/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group17/240094626/work_jvm_1/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/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LinkedList.java b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..f4c7556a2e --- /dev/null +++ b/group17/240094626/work_jvm_1/data-structure/src/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/group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java b/group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..b9d924a887 --- /dev/null +++ b/group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,73 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +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) { + if(null == className || "".equals(className)){ + return null; + } + className = className.replace(".", File.separator)+".class"; + Iterator it = clzPaths.iterator(); + byte[] bytes = null; + while(it.hasNext() && bytes == null){ + String filePath = it.next()+File.separator+className; + bytes = getClassFile(filePath); + } + return bytes; + + } + + + private byte[] getClassFile(String filePath) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + InputStream is = new FileInputStream(new File(filePath)); + byte[] buffer = new byte[1024]; + int len = 0; + while((len=is.read(buffer)) > 0){ + bos.write(buffer,0, len); + } + } catch (Exception e) { + e.printStackTrace(); + } + return bos.toByteArray(); + } + + + public void addClassPath(String path) { + if(null != path && !"".equals(path)){ + clzPaths.add(path); + } + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + Iterator it = clzPaths.iterator(); + while(it.hasNext()){ + if(sb.length() > 0){ + sb.append(";"); + } + sb.append(it.next()); + } + return sb.toString(); + } + + + + + +} diff --git a/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..a205045d2e --- /dev/null +++ b/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.test; + +import java.io.File; + +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 = "E:\\workspace-indigo-32-statsdb\\warm-up\\bin";//"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 { + private Node head; + private int size = 0; + + public void add(T o) { + if (head == null) { + head = new Node(null, o); + size++; + } else + addLast(o); + } + + private Node getLast() { + Node last = head; + while (last.next != null) { + last = last.next; + } + return last; + } + + private Node getNodeIndex(int index) { + if (index > size - 1) + throw new IndexOutOfBoundsException("size : " + size + ", index : " + index); + Node target = head; + for (int i = 0; i < size; i++) { + if (i == index) + return target; + target = target.next; + } + return null; + } + + public void add(int index, T o) { + Node node = getNodeIndex(index - 1); + Node nextNode = node.next; + node.next = new Node(nextNode, o); + size++; + } + + public T get(int index) { + Node node = getNodeIndex(index); + return node.data; + } + + public T remove(int index) { + Node prev = getNodeIndex(index - 1); + Node now = getNodeIndex(index); + prev.next = now.next; + size--; + return now.data; + } + + public int size() { + return size; + } + + public void addFirst(T o) { + if (head != null) + head = new Node(null, o); + else { + Node newNode = new Node(head, o); + head = newNode; + } + size++; + } + + public void addLast(T o) { + add(size, o); + } + + public T removeFirst() { + Node removeNode = head; + if (head != null) + head = head.next; + size--; + return removeNode == null ? null : removeNode.data; + } + + public T removeLast() { + Node last = getNodeIndex(size - 1); + Node prev = getNodeIndex(size - 2); + prev.next = null; + size--; + return last.data; + } + + public Iterator iterator() { + return null; + } + + private int getIndex(Node node) { + Node temp = head; + int index = 0; + while (temp != null) { + if (temp == node) { + return index; + } + } + return -1; + } + + private int getIndexByData(T data) { + Node temp = head; + int index = 0; + while (temp != null) { + if ((data == null && temp.data == null) || temp.data.equals(data)) + return index; + index++; + temp = temp.next; + } + return -1; + } + + + private static class Node { + T data; + Node next; + + Node(Node next, T data) { + this.next = next; + this.data = data; + } + + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + Node temp = head; + while (temp != null) { + sb.append(temp.data).append("-->"); + temp = temp.next; + } + return sb.toString().substring(0, sb.lastIndexOf("-->")); + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + Node cur = null; + Node prev = null; + while (head != null) { + cur = head; + head = head.next; + cur.next = prev; + prev = cur; + } + head = cur; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf() { + head = getNodeIndex(size / 2); + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + if (size <= (i + length) || i < 0) + throw new IndexOutOfBoundsException("size : " + size + ", i + length : " + (i + length)); + Node rightNode = getNodeIndex(i + length); + if (i == 0) + head = rightNode; + else { + Node leftNode = getNodeIndex(i - 1); + leftNode.next = rightNode; + } + } + + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * + * @param list + */ + public Object[] getElements(LinkedList list) { + Object[] result = new Object[list.size]; + if (list != null) { + for (int i = 0; i < list.size; i++) { + result[i] = get(list.get(i)); + } + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + * + * @param list + */ + + public void subtract(LinkedList list) { + if (list != null && list.size > 0) { + for (int i = 0; i < list.size; i++) { + int index = getIndexByData(list.get(i)); + if (index != -1) + remove(index); + else + throw new RuntimeException("wrong element of removed list"); + } + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues() { + Node temp = head; + List list = new ArrayList(); + int index = 0; + while (temp != null) { + if (list.contains(temp.data)) + remove(index--); + else + list.add(temp.data); + temp = temp.next; + index++; + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * + * @param min + * @param max + */ + public void removeRange(int min, int max) { + Integer first = (Integer) get(0); + Integer last = (Integer) getLast().data; + if (first > max || last < min) + return; + List indexRange = new ArrayList(); + Node temp = (Node) head; + int index = 0; + while (temp != null) { + if (temp.data >= min && temp.data <= max) { + indexRange.add(index); + } + index++; + temp = temp.next; + } + remove(indexRange.get(0), indexRange.size()); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * + * @param list + */ + public LinkedList intersection(LinkedList list) { + LinkedList newList = new LinkedList(); + merge(newList, (Node) this.head, list.head); + return newList; + } + + private void merge(LinkedList newList, Node thisHead, Node mergeHead) { + if (thisHead == null && mergeHead == null) + return; + if (thisHead == null) { + //无论是否包含,有元素的链表必须指向next + if (!newList.contains(mergeHead.data)) + newList.add(mergeHead.data); + mergeHead = mergeHead.next; + merge(newList, null, mergeHead); + } + if (mergeHead == null) { + if (!newList.contains(thisHead.data)) + newList.add(thisHead.data); + thisHead = thisHead.next; + merge(newList, thisHead, null); + } + //要再进行一次判断是因为递归到最底层return之后,返回上一层时某个链表已经为null了,但是上一层还是会将剩下的执行完 + if (thisHead != null && mergeHead != null) { + if (thisHead.data < mergeHead.data && !newList.contains(thisHead.data)) { + newList.add(thisHead.data); + thisHead = thisHead.next; + merge(newList, thisHead, mergeHead); + } else if (!newList.contains(mergeHead.data)) { + newList.add(mergeHead.data); + mergeHead = mergeHead.next; + merge(newList, thisHead, mergeHead); + } + } + } + + private boolean contains(Integer data) { + int index = this.getIndexByData((T) data); + return index != -1; + } +} diff --git a/group17/785396327/3.12/link/LinkedListTest.java b/group17/785396327/3.12/link/LinkedListTest.java new file mode 100644 index 0000000000..87edc35e99 --- /dev/null +++ b/group17/785396327/3.12/link/LinkedListTest.java @@ -0,0 +1,145 @@ +package link; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; + +/** + * Created by gongxun on 2017/3/13. + */ +public class LinkedListTest { + private LinkedList linkedList; + + @Before + public void startUp() { + linkedList = new LinkedList(); + linkedList.add("1"); + linkedList.add("2"); + linkedList.add("3"); +// System.out.println(linkedList); + } + + @After + public void tearDown() { + + } + + @Test + public void addFirst() { + linkedList.addFirst("1"); + System.out.println(linkedList); + } + + @Test + public void add() { + linkedList.add("1"); + linkedList.add("2"); + System.out.println(linkedList); + } + + @Test + public void add2() { + linkedList.add("1"); + linkedList.add("2"); + linkedList.add("3"); + linkedList.add(1, "0"); + System.out.println(linkedList); + } + + @Test + public void addLast() { + linkedList.add("1"); + linkedList.addLast("2"); + System.out.println(linkedList); + } + + @Test + public void get() { + String value = linkedList.get(2); + System.out.println(value); + } + + @Test + public void remove() { + String removeValue = linkedList.remove(3); + System.out.println(removeValue); + } + + @Test + public void reverse() { + linkedList.reverse(); + System.out.println(linkedList); + } + + @Test + public void removeFirstHalf() { + linkedList.removeFirstHalf(); + System.out.println(linkedList); + } + + @Test + public void removeByRange() { + linkedList.remove(0, 2); + System.out.println(linkedList); + } + + @Test + public void getElements() { + LinkedList indexList = new LinkedList(); + indexList.add(0); + indexList.add(2); + indexList.add(3); + Object[] elements = linkedList.getElements(indexList); + System.out.println(Arrays.toString(elements)); + } + + @Test + public void subtract() { + LinkedList indexList = new LinkedList(); + indexList.add("2"); + indexList.add("0"); + linkedList.subtract(indexList); + System.out.println(linkedList); + } + + @Test + public void removeDuplicateValues() { + linkedList.add("3"); + linkedList.add("7"); + linkedList.add("0"); + linkedList.add("1"); + System.out.println(linkedList); + linkedList.removeDuplicateValues(); + System.out.println(linkedList); + } + + @Test + public void removeRange() { + LinkedList list = new LinkedList(); + list.add(1); + list.add(3); + list.add(4); + list.add(5); + list.add(7); + System.out.println(list); + list.removeRange(1, 6); + System.out.println(list); + } + + @Test + public void intersection() { + LinkedList list1 = new LinkedList(); + list1.add(2); + list1.add(3); + list1.add(7); + LinkedList list2 = new LinkedList(); + list2.add(2); + list2.add(3); + list2.add(7); + LinkedList newList = list1.intersection(list2); + System.out.println(newList); + } + +} diff --git a/group17/785396327/3.26/jvm_1/ClassFileLoader.java b/group17/785396327/3.26/jvm_1/ClassFileLoader.java new file mode 100644 index 0000000000..95f68a5a7f --- /dev/null +++ b/group17/785396327/3.26/jvm_1/ClassFileLoader.java @@ -0,0 +1,50 @@ +package jvm_1; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by william on 2017/4/5. + */ +public class ClassFileLoader { + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + InputStream fis = null; + String filePath = clzPaths.get(0) + "\\\\" + className.replaceAll("\\.", "\\\\") + ".class"; + byte[] buffer = new byte[(int) new File(filePath).length()]; + try { + if (clzPaths.size() > 0 && className != null && !className.trim().equals("")) { + fis = new FileInputStream(filePath); + while (fis.read(buffer) != -1) ; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (fis != null) + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + fis = null; + } + } + return buffer; + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + public String getClassPath() { + StringBuilder sb = new StringBuilder(); + for (String clzPath : clzPaths) { + sb.append(clzPath).append(";"); + } + return sb.substring(0, sb.length() - 1); + } +} diff --git a/group24/798277403/src/week4/test/ClassFileloaderTest.java b/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java similarity index 75% rename from group24/798277403/src/week4/test/ClassFileloaderTest.java rename to group17/785396327/3.26/jvm_1/ClassFileloaderTest.java index aa8a84176a..067cd93c2b 100644 --- a/group24/798277403/src/week4/test/ClassFileloaderTest.java +++ b/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java @@ -1,18 +1,17 @@ -package week4.test; +package jvm_1; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import week4.loader.ClassFileLoader; /** - * Created by zhouliang on 2017-04-04. + * Created by william on 2017/4/5. */ public class ClassFileloaderTest { - static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + static String path1 = "D:\\workspace\\IDEA\\homework\\coding2017\\group17\\785396327\\out\\production\\785396327"; static String path2 = "C:\temp"; - static String path3 = "C:\\Users\\zhouliang\\Desktop\\mycoding\\coding2017\\group24\\798277403\\out\\production\\zhouliang"; + @Before @@ -40,14 +39,14 @@ public void testClassPath(){ public void testClassFileLength() { ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path3); + loader.addClassPath(path1); - String className = "week3.DownloadThread"; + String className = "jvm_1.EmployeeV1"; byte[] byteCodes = loader.readBinaryCode(className); // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(1751, byteCodes.length); + Assert.assertEquals(1020, byteCodes.length); } @@ -55,8 +54,8 @@ public void testClassFileLength() { @Test public void testMagicNumber(){ ClassFileLoader loader = new ClassFileLoader(); - loader.addClassPath(path3); - String className = "week4.test.EmployeeV1"; + loader.addClassPath(path1); + String className = "jvm_1.EmployeeV1"; byte[] byteCodes = loader.readBinaryCode(className); byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; @@ -68,6 +67,9 @@ public void testMagicNumber(){ + + + private String byteToHexString(byte[] codes ){ StringBuffer buffer = new StringBuffer(); for(int i=0;i clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + if (clzPaths.size()<=0){ + return null; + } + for (int i = 0; i < clzPaths.size(); i++) { + String path = clzPaths.get(i) + convertName(className); + File f = new File(path); + if(f.exists()){ + try { + return readFile(f); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + }else{ + f = null; + continue; + } + } + System.err.println("classpath:" +getClassPath()+ "class:" + convertName(className)+" not found."); + return null; + } + /** + * 文件读取二进制字节流 + * @param f + * @return + * @throws FileNotFoundException + */ + private byte[] readFile(File f) throws FileNotFoundException { + FileInputStream fis = new FileInputStream(f); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] b = new byte[BUFFERSIZE]; + try { + int len = 0; + while((len = fis.read(b))!=-1){ + baos.write(b,0,len); + } + } catch (IOException e) { + e.printStackTrace(); + } finally{ + try { + fis.close(); + baos.flush(); + baos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + return baos.toByteArray(); + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < clzPaths.size(); i++) { + sb.append(clzPaths.get(i)).append(";"); + } + int len = sb.length(); + if(len!=0){ + sb.deleteCharAt(len-1); + } + return sb.toString(); + } + + /** + * convert className to FilePath style className
+ * For example:com.sun.lang to \com\sun\lang + * + * @param className + * @return FilePath style className + */ + private String convertName(String className) { + StringBuilder sb = new StringBuilder(); + String[] pack = className.split("\\."); + for (int i = 0; i < pack.length; i++) { + sb.append("\\").append(pack[i]); + } + sb.append(".class"); + return sb.toString(); + } + + public static void main(String[] args) { + String d = "com.taiji.array.Load"; + ClassFileLoader cc = new ClassFileLoader(); + System.out.print(cc.convertName(d)); + } +} diff --git a/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java b/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..3e0f0d08b0 --- /dev/null +++ b/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java @@ -0,0 +1,29 @@ +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(); + + } +} diff --git a/group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java b/group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java new file mode 100644 index 0000000000..e26bd91e93 --- /dev/null +++ b/group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java @@ -0,0 +1,147 @@ +package com.coding.basic.LRU; + +public class LRUPageFrame { + private int capacity; + private Node first;// 链表头 + private Node last;// 链表尾 + private int length = 0; + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + // this loop select for pageNum,grow it first when 'found'. + for (Node n = first; n != null; n = n.next) { + if (n.pageNum == pageNum) { + growFirst(n); + return; + } + } + // if didn't found it + if (ensureFull()) { + removeLast(); + } + add(pageNum); + } + + private void add(int pageNum) { + if (isEmpty()) { + Node newNode = new Node(null, null, pageNum); + first = newNode; + last = newNode; + length++; + } else { + addToFirst(pageNum); + } + } + + private void addToFirst(int pageNum) { + Node newNode = new Node(null, null, pageNum); + newNode.next = first; + first.prev = newNode; + first = newNode; + length++; + } + + /** + * ensure the LRUPageFrame is full or Not + * + * @return if full return true,else false + */ + private boolean ensureFull() { + if (length < capacity) { + return false; + } else { + return true; + } + } + + /** + * grow the Node'position to first + * + * @param n + */ + private void growFirst(Node n) { + // if the node is already first ,return. + if (first.pageNum == n.pageNum) { + return; + } + remove(n); + addToFirst(n.pageNum); + } + + private void remove(Node n) { + if (isEmpty()) { + return; + } + if (n.next == null) { + removeLast(); + return; + } + if (n.prev == null) { + removeFirst(); + return; + } + Node prev = n.prev; + Node next = n.next; + n.next = null; + n.prev = null; + prev.next = next; + next.prev = prev; + length--; + } + + private void removeFirst() { + Node next = first.next; + first.next = null; + first = next; + } + + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev; + length--; + } + /** + * ensure the LRUPageFrame is empty or Not. + * @return + */ + public boolean isEmpty() { + return length < 1; + } + + 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(); + } + + 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; + } + } +} diff --git a/group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java b/group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java new file mode 100644 index 0000000000..bd06965cdd --- /dev/null +++ b/group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java @@ -0,0 +1,73 @@ +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 = "D:\\workProgram\\GitRepo\\coding2017\\group17\\82427129\\JavaUtil\\target\\classes"; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path2); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + @Test + public void testGetClassPath() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + } + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path2); + 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/group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java b/group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java new file mode 100644 index 0000000000..4dd2ca2baf --- /dev/null +++ b/group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java @@ -0,0 +1,29 @@ +package com.coding.basic.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/group17/article/20170326-20170402.md b/group17/article/20170326-20170402.md new file mode 100644 index 0000000000..5df4ce08e6 --- /dev/null +++ b/group17/article/20170326-20170402.md @@ -0,0 +1,56 @@ +# 自由写作 + +## 须知 +--- + +交作业时请在QQ 号后面填上各自的文章链接, 比如: + +51075907 http://m.blog.csdn.net/article/details?id=57083764 + +## 文章 +--- + +1204187480 + +102228177 + +876385982 + +785396327 + +1059107701 + +240094626 + +82427129 + +296910598 + +1264835468 http://www.jianshu.com/p/848fd6be5247 + +516886559 + +1282579502 https://www.evernote.com/l/AZ2Rx5pxgf9I-JqkSpFANMwTK9fXR0KFV50 + +614982500 + +865797761 + +1540186032 + +176653813 + +116665530 + +51075907 + +1158154002 + +345450234 + +919764878 + +1368331120 + +517970312 + diff --git a/group17/article/20170402-20170409.md b/group17/article/20170402-20170409.md new file mode 100644 index 0000000000..3d45ad0516 --- /dev/null +++ b/group17/article/20170402-20170409.md @@ -0,0 +1,56 @@ +# 自由写作 + +## 须知 +--- + +交作业时请在QQ 号后面填上各自的文章链接, 比如: + +51075907 http://m.blog.csdn.net/article/details?id=57083764 + +## 文章 +--- + +1204187480 + +102228177 + +876385982 + +785396327 + +1059107701 + +240094626 + +82427129 + +296910598 + +1264835468 + +516886559 + +1282579502 + +614982500 + +865797761 + +1540186032 + +176653813 + +116665530 + +51075907 + +1158154002 + +345450234 + +919764878 + +1368331120 + +517970312 + diff --git a/group17/article/template.md b/group17/article/template.md index 09c7951d71..0b06ef733e 100644 --- a/group17/article/template.md +++ b/group17/article/template.md @@ -10,9 +10,9 @@ ## 文章 --- -1204187480 http://blog.leanote.com/post/luoziyihao/js%E9%97%AD%E5%8C%85 +1204187480 -102228177 +102228177 http://note.youdao.com/noteshare?id=1f8f4a9d861e24948cdf0219a0d39f4e 876385982 @@ -26,11 +26,11 @@ 296910598 -1264835468 http://www.jianshu.com/p/634ca8cdd6e3 +1264835468 516886559 -1282579502 https://www.evernote.com/shard/s413/sh/142601dd-edc3-4e37-871e-37a7489d7634/a092bf080e1aefbaeab96d34edac8cf0 +1282579502 614982500 diff --git a/group17/count/homework.md b/group17/count/homework.md index e474336779..640cf4698f 100644 --- a/group17/count/homework.md +++ b/group17/count/homework.md @@ -17,3 +17,7 @@ * [20170305-20170312](https://github.com/luoziyihao/coding2017/blob/master/group17/article/20170305-20170312.md) + * [20170326-20170402](https://github.com/luoziyihao/coding2017/blob/master/group17/article/20170326-20170402.md) + * [20170402-20170409](https://github.com/luoziyihao/coding2017/blob/master/group17/article/20170402-20170409.md) + +20170326-20170402.md 20170402-20170409.md diff --git a/group17/count/reward.md b/group17/count/reward.md new file mode 100644 index 0000000000..4a0fe7ea81 --- /dev/null +++ b/group17/count/reward.md @@ -0,0 +1,16 @@ +## 17组 201703 获奖 + +### 代码坚持奖 + +82427129 +1282579502 +102228177 +1264835468 + +### 博客坚持奖 + +82427129 +1282579502 +102228177 +1264835468 + diff --git a/group22/1158477486/src/TestCollection/ArrayUtil.java b/group22/1158477486/src/TestCollection/ArrayUtil.java new file mode 100644 index 0000000000..c5df8c2b1c --- /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..b7103b9c5c --- /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..ddcbd5862a --- /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/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..0d9e351975 --- /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..2afed85ba7 --- /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..5d7da6d0bb --- /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..0957eaf7f4 --- /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..1551a80b3d --- /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..ce045393b1 --- /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..bf9807b307 --- /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..aba6afc252 --- /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..c7d47979c8 --- /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..836342423b --- /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..b1b7be257e --- /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..c7f1a71bf4 --- /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..f4a7d55715 --- /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..41a08c7712 --- /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..6bd3c6fa75 --- /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..7e1b049d8c --- /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..2548fa6b22 --- /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/group24/798277403/src/week2/litestruts/View.java b/group22/2622819383/Task2/litestruts/View.java similarity index 93% rename from group24/798277403/src/week2/litestruts/View.java rename to group22/2622819383/Task2/litestruts/View.java index 01a422a808..4f2ca4ec30 100644 --- a/group24/798277403/src/week2/litestruts/View.java +++ b/group22/2622819383/Task2/litestruts/View.java @@ -1,4 +1,4 @@ -package week2.litestruts; + import java.util.Map; 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/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/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/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/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/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/group23/565832157/src/com/coding/basic/LinkedList.java b/group23/565832157/src/com/coding/basic/LinkedList.java index 09fe0a8ff3..77657e57c1 100644 --- a/group23/565832157/src/com/coding/basic/LinkedList.java +++ b/group23/565832157/src/com/coding/basic/LinkedList.java @@ -1,3 +1,145 @@ +<<<<<<< HEAD:liuxin/src/com/coding/basic/LinkedList.java +package com.coding.basic; + +public class LinkedList implements List { + private int size; + + 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 size; + } + + 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; + } + + /** + * 把该链表逆置 + * head head + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + /** + * 长度超过1的单链表需要逆转 + */ + if(size>1){ + Node pre = head; + Node cur = head.next; + Node next = null; + while(cur!=null){ + next = cur.next; + cur.next = pre; + pre = cur; + cur = next; + } + + } + } + + + /** + * 删除一个单链表的前半部分 + * 例如: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; + } +} +======= package com.coding.basic; public class LinkedList implements List { @@ -120,3 +262,4 @@ public LinkedList intersection( LinkedList list){ return null; } } +>>>>>>> upstream/master:group23/565832157/src/com/coding/basic/LinkedList.java diff --git a/group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java b/group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java new file mode 100644 index 0000000000..f6586ce761 --- /dev/null +++ b/group24/1148285693/learning2017/common/src/main/java/me/lzb/common/utils/ByteUtils.java @@ -0,0 +1,26 @@ +package me.lzb.common.utils; + +/** + * Created by LZB on 2017/4/14. + */ +public class ByteUtils { + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i + + me.lzb + common + 1.0 + diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayList.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayList.java similarity index 98% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayList.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayList.java index 080aa4f724..af897cd58f 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayList.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayList.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 简易ArrayList diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayUtil.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayUtil.java similarity index 99% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayUtil.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayUtil.java index de101845aa..eab32c80cc 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/ArrayUtil.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/ArrayUtil.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; public class ArrayUtil { diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/BinaryTreeNode.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/BinaryTreeNode.java similarity index 97% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/BinaryTreeNode.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/BinaryTreeNode.java index dfcaa60300..88395e3010 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/BinaryTreeNode.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 左边比父节点小,右边比父节点大 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java new file mode 100644 index 0000000000..e30cc00cc2 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/InfixExpr.java @@ -0,0 +1,161 @@ +package me.lzb.basic; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Created by LZB on 2017/4/15. + */ +public class InfixExpr { + + + private String expr; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + List list = processExpr(); + + Stack symbolStack = new Stack<>(); + Stack numberStack = new Stack<>(); + + boolean calLevel2 = false; + for (Node n : list) { + if (n.isNumber) { + numberStack.push(n.number); + if (calLevel2) { + calculate(symbolStack, numberStack, false); + calLevel2 = false; + } + } else { + symbolStack.push(n.symbol); + + if (n.isLevel2()) { + calLevel2 = true; + } + } + } + + + Stack tn = new Stack<>(); + int nsize = numberStack.size(); + for (int i = 0; i < nsize; i++) { + tn.push(numberStack.pop()); + } + + numberStack = tn; + + + Stack ts = new Stack<>(); + int ssize = symbolStack.size(); + for (int i = 0; i < ssize; i++) { + ts.push(symbolStack.pop()); + } + + symbolStack = ts; + + + while (!symbolStack.isEmpty()) { + calculate(symbolStack, numberStack, true); + } + + + return numberStack.pop(); + } + + + + private List processExpr() { + List list = new ArrayList<>(); + char[] array = this.expr.toCharArray(); + String number = ""; + for (int i = 0; i < array.length; i++) { + if (Character.isDigit(array[i])) { + number = number + String.valueOf(array[i]); + } else { + Node num = new Node(Float.valueOf(number), null, true, -1); + number = ""; + int calLevel = "+-".indexOf(array[i]) >= 0 ? 1 : 2; + Node sym = new Node(0, String.valueOf(array[i]), false, calLevel); + list.add(num); + list.add(sym); + } + } + + Node num = new Node(Float.valueOf(number), null, true, -1); + list.add(num); + return list; + } + + + private void calculate(Stack symbolStack, Stack numberStack, boolean isRe) { + if (symbolStack.isEmpty()) { + return; + } + + + String symbole = symbolStack.pop(); + + float right; + float left; + + if(isRe){ + left = numberStack.pop(); + right = numberStack.pop(); + }else { + right = numberStack.pop(); + left = numberStack.pop(); + } + + + + float r = calculate(symbole, left, right); + + numberStack.push(r); + } + + + private float calculate(String symbol, float left, float right) { + if ("+".equals(symbol)) { + return left + right; + } + + if ("-".equals(symbol)) { + return left - right; + } + + if ("*".equals(symbol)) { + return left * right; + } + + if ("/".equals(symbol)) { + return left / right; + } + + return 0; + } + + + private class Node { + float number; + String symbol; + boolean isNumber; + int calLevel;//加减1,乘除2 + + public Node(float number, String symbol, boolean isNumber, int calLevel) { + this.number = number; + this.symbol = symbol; + this.isNumber = isNumber; + this.calLevel = calLevel; + } + + private boolean isLevel2() { + return calLevel == 2; + } + } + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Iterator.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Iterator.java similarity index 80% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Iterator.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Iterator.java index b65f73b2e3..86e8cae942 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Iterator.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Iterator.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * Created by LZB on 2017/3/11. diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/algorithm/LRUPageFrame.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LRUPageFrame.java similarity index 99% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/algorithm/LRUPageFrame.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LRUPageFrame.java index 1f1d0a36b7..6e0e570ce6 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/algorithm/LRUPageFrame.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LRUPageFrame.java @@ -1,4 +1,4 @@ -package me.lzb.algorithm; +package me.lzb.basic; /** * 用双向链表实现LRU算法 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/LinkedList.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LinkedList.java similarity index 99% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/LinkedList.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LinkedList.java index f79b7eaf18..268b69bf50 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/LinkedList.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/LinkedList.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/List.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/List.java similarity index 86% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/List.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/List.java index 8f6478c49e..df7f30812b 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/List.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/List.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * list接口 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Queue.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Queue.java similarity index 94% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Queue.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Queue.java index 35dc95f688..08303d3fb5 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Queue.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Queue.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 先进先出 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Stack.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Stack.java similarity index 97% rename from group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Stack.java rename to group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Stack.java index 367b7210e6..60785110eb 100644 --- a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/datastructure/Stack.java +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/Stack.java @@ -1,4 +1,4 @@ -package me.lzb.datastructure; +package me.lzb.basic; /** * 先进后出 diff --git a/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java new file mode 100644 index 0000000000..547eb6105f --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/main/java/me/lzb/basic/StackUtil.java @@ -0,0 +1,155 @@ +package me.lzb.basic; + +import java.util.Stack; + +public class StackUtil { + + public static void bad_reverse(Stack s) { + + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + Stack t = new Stack<>(); + for (Integer i : s) { + t.push(i); + } + + s.clear(); + + int size = t.size(); + for (int i = 0; i < size; i++) { + s.push(t.pop()); + } + + } + + public static void addToBottom(Stack s, Integer value) { + Stack t = new Stack<>(); + int size = s.size(); + for (int i = 0; i < size; i++) { + t.push(s.pop()); + } + + s.clear(); + + s.push(value); + + for (int i = 0; i < size; i++) { + s.push(t.pop()); + } + + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + Stack t = new Stack(); + int size = s.size(); + for (int i = 0; i < size; i++) { + Object ro = s.pop(); + if (!ro.equals(o)) { + t.push(ro); + } + } + + s.clear(); + + int sizet = t.size(); + for (int i = 0; i < sizet; i++) { + s.push(t.pop()); + } + + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + Object[] array = new Object[len]; + for (int i = 0; i < len; i++) { + array[i] = s.pop(); + } + + for (int i = len - 1; i >= 0; i--) { + s.push(array[i]); + } + return array; + } + + /** + * 字符串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) { + char[] array = s.toCharArray(); + Stack stack = new Stack<>(); + for (int i = 0; i < array.length; i++) { + stack.push(String.valueOf(array[i])); + } + + + int a = -1; + int b = -1; + int c = -1; + + + for (int i = 0; i < array.length; i++) { + String cc = stack.pop(); + + if ("{}".indexOf(cc) >= 0) { + if (a == -1) { + a = i; + } else { + if (stack.size() != a) { + return false; + } + } + } + + if ("[]".indexOf(cc) >= 0) { + + if (b == -1) { + b = i; + } else { + if (stack.size() != b) { + return false; + } + } + + } + + if ("()".indexOf(cc) >= 0) { + + if (c == -1) { + c = i; + } else { + if (stack.size() != c) { + return false; + } + } + + } + + } + return true; + } + + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/ArrayListTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/ArrayListTest.java similarity index 96% rename from group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/ArrayListTest.java rename to group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/ArrayListTest.java index dcb879a948..efcfdbae1d 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/ArrayListTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/ArrayListTest.java @@ -1,7 +1,7 @@ -package me.lzb.datastructure; +package me.lzb.basic; -import me.lzb.datastructure.ArrayList; -import me.lzb.datastructure.Iterator; +import me.lzb.basic.ArrayList; +import me.lzb.basic.Iterator; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java new file mode 100644 index 0000000000..5ca7621354 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/InfixExprTest.java @@ -0,0 +1,48 @@ +package me.lzb.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/algorithm/LRUPageFrameTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LRUPageFrameTest.java similarity index 95% rename from group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/algorithm/LRUPageFrameTest.java rename to group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LRUPageFrameTest.java index 66bfd42119..828eab0881 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/algorithm/LRUPageFrameTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LRUPageFrameTest.java @@ -1,5 +1,6 @@ -package me.lzb.algorithm; +package me.lzb.basic; +import me.lzb.basic.LRUPageFrame; import org.junit.Assert; import org.junit.Test; diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/LinkedListTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LinkedListTest.java similarity index 98% rename from group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/LinkedListTest.java rename to group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LinkedListTest.java index 1914195aa5..6f02328060 100644 --- a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/datastructure/LinkedListTest.java +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/LinkedListTest.java @@ -1,7 +1,7 @@ -package me.lzb.datastructure; +package me.lzb.basic; -import me.lzb.datastructure.Iterator; -import me.lzb.datastructure.LinkedList; +import me.lzb.basic.Iterator; +import me.lzb.basic.LinkedList; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; diff --git a/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java new file mode 100644 index 0000000000..48589f57d3 --- /dev/null +++ b/group24/1148285693/learning2017/learning-basic/src/test/java/me/lzb/basic/StackUtilTest.java @@ -0,0 +1,78 @@ +package me.lzb.basic; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Stack; + +public class StackUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddToBottom() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..fd000bdcb3 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/AttributeInfo.java @@ -0,0 +1,22 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public abstract class AttributeInfo { + + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + + int attrNameIndex; + int attrLen; + + public AttributeInfo(int attrNameIndex, int attrLen) { + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..2addebeb39 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/CodeAttr.java @@ -0,0 +1,52 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public class CodeAttr extends AttributeInfo { + private int maxStack; + private int maxLocals; + private int codeLen; + private String code; + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen, String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + + public String getCode() { + return code; + } + + public LineNumberTable getLineNumTable() { + return lineNumTable; + } + + public void setLineNumTable(LineNumberTable lineNumTable) { + this.lineNumTable = lineNumTable; + } + + public LocalVariableTable getLocalVarTable() { + return localVarTable; + } + + public void setLocalVarTable(LocalVariableTable localVarTable) { + this.localVarTable = localVarTable; + } + + public StackMapTable getStackMapTable() { + return stackMapTable; + } + + public void setStackMapTable(StackMapTable stackMapTable) { + this.stackMapTable = stackMapTable; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java new file mode 100644 index 0000000000..e621cf925a --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberItem.java @@ -0,0 +1,31 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/16. + */ +public class LineNumberItem { + int startPC; + int lineNum; + + + public LineNumberItem(int startPC, int lineNum) { + this.startPC = startPC; + this.lineNum = lineNum; + } + + public int getStartPC() { + return startPC; + } + + // public void setStartPC(int startPC) { +// this.startPC = startPC; +// } + + public int getLineNum() { + return lineNum; + } + +// public void setLineNum(int lineNum) { +// this.lineNum = lineNum; +// } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..5bf7b4759b --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LineNumberTable.java @@ -0,0 +1,23 @@ +package me.lzb.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/15. + */ +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList<>(); + + + public void addLineNumberItem(LineNumberItem item) { + this.items.add(item); + } + + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..decef772a3 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableItem.java @@ -0,0 +1,62 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + + + public LocalVariableItem(int startPC, int length, int nameIndex, int descIndex, int index){ + this.startPC = startPC; + this.length = length; + this.nameIndex = nameIndex; + this.descIndex = descIndex; + this.index = index; + } + + + public int getStartPC() { + return startPC; + } + + public void setStartPC(int startPC) { + this.startPC = startPC; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescIndex() { + return descIndex; + } + + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..9dca129d71 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/LocalVariableTable.java @@ -0,0 +1,20 @@ +package me.lzb.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/15. + */ +public class LocalVariableTable extends AttributeInfo { + List items = new ArrayList<>(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..0b8947bdf8 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/attr/StackMapTable.java @@ -0,0 +1,15 @@ +package me.lzb.jvm.attr; + +/** + * Created by LZB on 2017/4/15. + */ +public class StackMapTable extends AttributeInfo { + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen, String code) { + super(attrNameIndex, attrLen); + this.originalCode = code; + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..224714a010 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/AccessFlag.java @@ -0,0 +1,29 @@ +package me.lzb.jvm.clz; + +/** + * Created by LZB on 2017/4/14. + */ +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; + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..c5de9be5ce --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassFile.java @@ -0,0 +1,131 @@ +package me.lzb.jvm.clz; + +import me.lzb.jvm.constant.ConstantPool; +import me.lzb.jvm.field.Field; +import me.lzb.jvm.method.Method; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/14. + */ +public class ClassFile { + + private String magicNumber; + + private int minorVersion; + + private int majorVersion; + + private AccessFlag accessFlag; + + private ClassIndex clzIndex; + + + private ConstantPool constantPool; + + private List fields = new ArrayList<>(); + + private List methods = new ArrayList<>(); + + + public String getMagicNumber() { + return magicNumber; + } + + public void setMagicNumber(String magicNumber) { + this.magicNumber = magicNumber; + } + + 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 AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public void setConstantPool(ConstantPool constantPool) { + this.constantPool = constantPool; + } + + + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } + + + + + + public ClassIndex getClzIndex() { + return clzIndex; + } + + public void setClzIndex(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()); + + } + + + + + public int getConstantPoolCount() { + return constantPool.getSize(); + } + + public void addField(Field f){ + this.fields.add(f); + } + + public void addMethod(Method m){ + this.methods.add(m); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..8916290057 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/clz/ClassIndex.java @@ -0,0 +1,25 @@ +package me.lzb.jvm.clz; + +/** + * Created by LZB on 2017/4/14. + */ +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; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..200e59834a --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ClassInfo.java @@ -0,0 +1,33 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/14. + */ +public class ClassInfo extends ConstantInfo{ + private int type = ConstantInfo.Class_info; + private int utf8Index; + + public ClassInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + public int getUtf8Index() { + return utf8Index; + } + + public void setUtf8Index(int utf8Index) { + this.utf8Index = utf8Index; + } + + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..3bbabf2180 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantInfo.java @@ -0,0 +1,44 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/14. + */ +public abstract class ConstantInfo { + + public static final String MAGIC_NUMBER = "cafebabe"; + + public static final int Class_info = 7; + + public static final int Fieldref_info = 9; + + public static final int Methodref_info = 10; + + public static final int String_info = 8; + + public static final int NameAndType_info = 12; + + public static final int Utf8_info = 1; + + + + protected ConstantPool constantPool; + + + public ConstantInfo(){ + + } + + public ConstantInfo(ConstantPool pool) { + this.constantPool = pool; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return this.constantPool.getConstantInfo(index); + } + + + public abstract int getType(); +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..d78f0a71f4 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package me.lzb.jvm.constant; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by LZB on 2017/4/14. + */ +public class ConstantPool { + + private List constantInfoList = new ArrayList<>(); + + + + public void addConstantInfo(ConstantInfo constantInfo){ + constantInfoList.add(constantInfo); + } + + + public int getSize(){ + return constantInfoList.size() > 1 ? constantInfoList.size() - 1 : 0; + } + + public ConstantInfo getConstantInfo(int index){ + return constantInfoList.get(index); + } + + public String getUTF8String(int index){ + return ((UTF8Info)this.constantInfoList.get(index)).getValue(); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..0ebab33b39 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/FieldRefInfo.java @@ -0,0 +1,35 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class FieldRefInfo extends ConstantInfo{ + private int type = ConstantInfo.Fieldref_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; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..263c185af5 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/MethodRefInfo.java @@ -0,0 +1,36 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class MethodRefInfo extends ConstantInfo { + private int type = ConstantInfo.Methodref_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; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..bdf158ec37 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,36 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class NameAndTypeInfo extends ConstantInfo { + private int type = ConstantInfo.NameAndType_info; + + private int index1; + private int index2; + + public NameAndTypeInfo(ConstantPool pool) { + super(pool); + } + + @Override + public int getType() { + return type; + } + + 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; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..7f9debba3b --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/NullConstantInfo.java @@ -0,0 +1,12 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/14. + */ +public class NullConstantInfo extends ConstantInfo{ + + @Override + public int getType() { + return -1; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..8ba36d8cfc --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +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; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..d3f35c2fd7 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/constant/UTF8Info.java @@ -0,0 +1,38 @@ +package me.lzb.jvm.constant; + +/** + * Created by LZB on 2017/4/15. + */ +public class UTF8Info extends ConstantInfo { + private int type = ConstantInfo.Class_info; + + private String value; + + private int length; + + public UTF8Info(ConstantPool pool) { + super(pool); + } + + + @Override + public int getType() { + return type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java new file mode 100644 index 0000000000..f388fd01bf --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/field/Field.java @@ -0,0 +1,30 @@ +package me.lzb.jvm.field; + +import me.lzb.jvm.constant.ConstantPool; + +/** + * Created by LZB on 2017/4/15. + */ +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private ConstantPool pool; + + public Field(int accessFlag, int nameIndex, int descriptorIndex ,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + @Override + public String toString() { + String key = pool.getUTF8String(nameIndex); + String value = pool.getUTF8String(descriptorIndex); + return key + ":" + value; + } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..593694066d --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileLoader.java @@ -0,0 +1,56 @@ +package me.lzb.jvm.loader; + + +import me.lzb.common.utils.FileUtils; +import me.lzb.jvm.clz.ClassFile; + +import java.io.File; +import java.io.IOException; +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) throws IOException { +// String fileName = className.replaceAll(".*\\.", "") + ".class"; +// String pkg = className.replaceAll("\\.[^\\.]+$", ""); +// String packagePath = pkg.replaceAll("\\.", "\\\\"); + + className = className.replace('.', File.separatorChar) + ".class"; + for (String s : clzPaths) { + byte[] data = FileUtils.readByteCodes(s + className); + if (data != null) { + return data; + } + } + + throw new IOException(className + "is not exist"); + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + public String getClassPath() { + StringBuilder buffer = new StringBuilder(); + for (Iterator iterator = clzPaths.iterator(); iterator.hasNext(); ) { + buffer.append(iterator.next() + (iterator.hasNext() ? ";" : "")); + } + return buffer.toString(); + } + + + public ClassFile loadClass(String className) throws IOException { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(codes); + return parser.parse(); + } + + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..bfd3cbc2c0 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/loader/ClassFileParser.java @@ -0,0 +1,331 @@ +package me.lzb.jvm.loader; + +import me.lzb.common.utils.ByteUtils; +import me.lzb.common.utils.StringUtils; +import me.lzb.jvm.attr.*; +import me.lzb.jvm.clz.AccessFlag; +import me.lzb.jvm.clz.ClassFile; +import me.lzb.jvm.clz.ClassIndex; +import me.lzb.jvm.constant.*; +import me.lzb.jvm.field.Field; +import me.lzb.jvm.method.Method; + +import java.io.UnsupportedEncodingException; + +/** + * 处理字class文件字节流 + * Created by LZB on 2017/4/14. + */ +public class ClassFileParser { + + + private final byte[] data; + + private int index; + + public ClassFileParser(byte[] data) { + this.data = data; + } + + + public ClassFile parse() { + ClassFile classFile = new ClassFile(); + parserMagicNumber(classFile); + + if (!StringUtils.equals(classFile.getMagicNumber(), ConstantInfo.MAGIC_NUMBER)) { + throw new RuntimeException("It is not a java class file."); + } + + parserVersion(classFile); + + parserConstantPool(classFile); + + parserAccessFlag(classFile); + + parserClassIndex(classFile); + + parserInterface(classFile); + + parserField(classFile); + + parserMethod(classFile); + + return classFile; + } + + + private byte[] nextBytes(int nextLength) { + byte[] target = new byte[nextLength]; + System.arraycopy(data, index, target, 0, nextLength); + index = index + nextLength; + return target; + } + + private int nextBytesToInt(int nextLength) { + return ByteUtils.byteToInt(nextBytes(nextLength)); + } + + private String nextBytesToString(int nextLength) { + return ByteUtils.byteToHexString(nextBytes(nextLength)); + } + + + private void parserMagicNumber(ClassFile classFile) { + this.index = 0; + classFile.setMagicNumber(nextBytesToString(4)); + } + + private void parserVersion(ClassFile classFile) { + classFile.setMinorVersion(nextBytesToInt(2)); + classFile.setMajorVersion(nextBytesToInt(2)); + } + + private void parserConstantPool(ClassFile classFile) { + int count = nextBytesToInt(2); + + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i < count; i++) { + + int tag = nextBytesToInt(1); + + if (tag == ConstantInfo.Class_info) { + ClassInfo classInfo = new ClassInfo(pool); + classInfo.setUtf8Index(nextBytesToInt(2)); + + pool.addConstantInfo(classInfo); + continue; + } + + if (tag == ConstantInfo.Fieldref_info) { + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(nextBytesToInt(2)); + fieldRefInfo.setNameAndTypeIndex(nextBytesToInt(2)); + + pool.addConstantInfo(fieldRefInfo); + continue; + } + + if (tag == ConstantInfo.Methodref_info) { + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(nextBytesToInt(2)); + methodRefInfo.setNameAndTypeIndex(nextBytesToInt(2)); + + pool.addConstantInfo(methodRefInfo); + continue; + } + + if (tag == ConstantInfo.NameAndType_info) { + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setIndex1(nextBytesToInt(2)); + nameAndTypeInfo.setIndex2(nextBytesToInt(2)); + + pool.addConstantInfo(nameAndTypeInfo); + continue; + } + + if (tag == ConstantInfo.String_info) { + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setIndex(nextBytesToInt(2)); + + pool.addConstantInfo(stringInfo); + continue; + } + + if (tag == ConstantInfo.Utf8_info) { + UTF8Info utf8Info = new UTF8Info(pool); + int len = nextBytesToInt(2); + byte[] data = nextBytes(len); + String value = null; + try { + value = new String(data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + utf8Info.setLength(len); + utf8Info.setValue(value); + + pool.addConstantInfo(utf8Info); + continue; + } + + + throw new RuntimeException("the constant pool tag " + tag + " has not been implemented yet." + i); + } + + + classFile.setConstantPool(pool); + } + + + private void parserAccessFlag(ClassFile classFile) { + AccessFlag flag = new AccessFlag(nextBytesToInt(2)); + classFile.setAccessFlag(flag); + } + + + private void parserClassIndex(ClassFile classFile) { + ClassIndex clzIndex = new ClassIndex(); + + int thisClassIndex = nextBytesToInt(2); + int superClassIndex = nextBytesToInt(2); + clzIndex.setThisClassIndex(thisClassIndex); + clzIndex.setSuperClassIndex(superClassIndex); + + classFile.setClzIndex(clzIndex); + } + + private void parserInterface(ClassFile classFile) { + int count = nextBytesToInt(2); + //TODO 实现interface + } + + + private void parserField(ClassFile classFile) { + int count = nextBytesToInt(2); + for (int i = 1; i <= count; i++) { + int accessFlags = nextBytesToInt(2); + int nameIndex = nextBytesToInt(2); + int descriptorIndex = nextBytesToInt(2); + int attributesCount = nextBytesToInt(2); + + if (attributesCount > 0) { + throw new RuntimeException("Field Attribute has not been implement"); + } + + Field field = new Field(accessFlags, nameIndex, descriptorIndex, classFile.getConstantPool()); + classFile.addField(field); + } + } + + private void parserMethod(ClassFile classFile) { + int count = nextBytesToInt(2); + for (int i = 1; i <= count; i++) { + int accessFlags = nextBytesToInt(2); + int nameIndex = nextBytesToInt(2); + int descriptorIndex = nextBytesToInt(2); + int attributesCount = nextBytesToInt(2); + + + Method method = new Method(accessFlags, nameIndex, descriptorIndex); + + + for (int j = 1; j <= attributesCount; j++) { + + int attributeNameIndex = nextBytesToInt(2); + + String attributeName = classFile.getConstantPool().getUTF8String(attributeNameIndex); + + if (StringUtils.equalsIgnoreCase(attributeName, AttributeInfo.CODE)) { + parserCodeAttr(attributeNameIndex, method, classFile); + continue; + } + + + throw new RuntimeException("only CODE attribute is implemented."); + } + + classFile.addMethod(method); + + } + } + + + private void parserCodeAttr(int attributeNameIndex, Method method, ClassFile classFile) { + int attributeLength = nextBytesToInt(4); + int maxStack = nextBytesToInt(2); + int maxLocals = nextBytesToInt(2); + int codeLength = nextBytesToInt(4); + + String code = nextBytesToString(codeLength); + CodeAttr codeAttr = new CodeAttr(attributeNameIndex, attributeLength, maxStack, maxLocals, codeLength, code); + + int exceptionTableLength = nextBytesToInt(2); + if (exceptionTableLength > 0) { + String exceptionTable = nextBytesToString(exceptionTableLength); + //TODO 异常 + } + + + int subAttrCount = nextBytesToInt(2); + for (int k = 1; k <= subAttrCount; k++) { + int subAttrIndex = nextBytesToInt(2); + + String subAttrName = classFile.getConstantPool().getUTF8String(subAttrIndex); + + if (StringUtils.equalsIgnoreCase(subAttrName, AttributeInfo.LINE_NUM_TABLE)) { + + parserLineNumberTable(codeAttr, subAttrIndex); + continue; + } + + if (StringUtils.equalsIgnoreCase(subAttrName, AttributeInfo.LOCAL_VAR_TABLE)) { + parserLocalVariableTable(codeAttr, subAttrIndex); + continue; + } + + if (StringUtils.equalsIgnoreCase(subAttrName, AttributeInfo.STACK_MAP_TABLE)) { + parserStackMapTable(codeAttr, subAttrIndex); + continue; + } + + + throw new RuntimeException("Need code to process" + subAttrName); + } + + + method.setCodeAttr(codeAttr); + } + + + private void parserLineNumberTable(CodeAttr codeAttr, int attributeNameIndex) { +// int attributeNameIndex = nextBytesToInt(2); + int attributeLength = nextBytesToInt(4); + + int lineNumberTableLength = nextBytesToInt(2); + + LineNumberTable table = new LineNumberTable(attributeNameIndex, attributeLength); + + for (int l = 1; l <= lineNumberTableLength; l++) { + int startPc = nextBytesToInt(2); + int lineNumber = nextBytesToInt(2); + LineNumberItem item = new LineNumberItem(startPc, lineNumber); + table.addLineNumberItem(item); + } + + codeAttr.setLineNumTable(table); + } + + + private void parserLocalVariableTable(CodeAttr codeAttr, int attributeNameIndex) { +// int attributeNameIndex = nextBytesToInt(2); + int attributeLength = nextBytesToInt(4); + + int localVariableTableLength = nextBytesToInt(2); + + LocalVariableTable table = new LocalVariableTable(attributeNameIndex, attributeLength); + + for (int l = 1; l <= localVariableTableLength; l++) { + int startPc = nextBytesToInt(2); + int lineNumber = nextBytesToInt(2); + int nameIndex = nextBytesToInt(2); + int descriptorIndex = nextBytesToInt(2); + int index = nextBytesToInt(2); + LocalVariableItem item = new LocalVariableItem(startPc, lineNumber, nameIndex, descriptorIndex, index); + table.addLocalVariableItem(item); + } + + codeAttr.setLocalVarTable(table); + } + + private void parserStackMapTable(CodeAttr codeAttr, int attributeNameIndex) { +// int attributeNameIndex = nextBytesToInt(2); + int attributeLength = nextBytesToInt(4); + String code = nextBytesToString(attributeLength); + StackMapTable table = new StackMapTable(attributeNameIndex, attributeLength, code); + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + codeAttr.setStackMapTable(table); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java new file mode 100644 index 0000000000..9c3e9ad984 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/jvm/method/Method.java @@ -0,0 +1,65 @@ +package me.lzb.jvm.method; + +import me.lzb.jvm.attr.CodeAttr; + +/** + * Created by LZB on 2017/4/15. + */ +public class Method { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + +// private ClassFile clzFile; + + + public Method(/*ClassFile clzFile,*/ int accessFlag, int nameIndex, int descriptorIndex) { +// this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public int getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(int accessFlag) { + this.accessFlag = accessFlag; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr codeAttr) { + this.codeAttr = codeAttr; + } + +// public ClassFile getClzFile() { +// return clzFile; +// } +// +// public void setClzFile(ClassFile clzFile) { +// this.clzFile = clzFile; +// } +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java b/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java deleted file mode 100644 index 86f017cebf..0000000000 --- a/group24/1148285693/learning2017/mini-jvm/src/main/java/me/lzb/loader/ClassFileLoader.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.lzb.loader; - -import me.lzb.utils.FileUtils; -import me.lzb.utils.StringUtils; - -import java.io.IOException; -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) throws IOException { - String fileName = className.replaceAll(".*\\.", "") + ".class"; - String pkg = className.replaceAll("\\.[^\\.]+$", ""); - String packagePath = pkg.replaceAll("\\.", "\\\\"); - - - String path = ""; - for (String s : clzPaths) { - if (FileUtils.isFileExist(s + packagePath, fileName)){ - path = s; - break; - } - } - - if(StringUtils.isBlank(path)){ - throw new IOException("class file not found"); - } - - return FileUtils.readByteCodes(path + packagePath + "\\" + fileName); - - } - - - public void addClassPath(String path) { - clzPaths.add(path); - } - - - - public String getClassPath(){ - StringBuilder buffer = new StringBuilder(); - for (Iterator iterator = clzPaths.iterator(); iterator.hasNext();) { - buffer.append(iterator.next() + (iterator.hasNext() ? ";" : "")); - } - return buffer.toString(); - } - - - - -} diff --git a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java new file mode 100644 index 0000000000..f41b313c97 --- /dev/null +++ b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/ClassFileloaderTest.java @@ -0,0 +1,269 @@ +package me.lzb.jvm; + +import me.lzb.common.utils.ByteUtils; +import me.lzb.jvm.clz.ClassFile; +import me.lzb.jvm.clz.ClassIndex; +import me.lzb.jvm.constant.*; +import me.lzb.jvm.field.Field; +import me.lzb.jvm.loader.ClassFileLoader; +import me.lzb.jvm.method.Method; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.List; + + +public class ClassFileloaderTest { + + + static String path1 = EmployeeV1.class.getResource("/").getPath(); +// static String path1 = "D:\\code\\learning\\coding2017\\group24\\1148285693\\learning2017\\mini-jvm\\target\\test-classes\\"; + static String path2 = "C:\\temp"; + + static String className = "me.lzb.jvm.EmployeeV1"; + + private static final String FULL_QUALIFIED_CLASS_NAME = "me/lzb/jvm/EmployeeV1"; +// private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + + @Test + public void testPath() { + + String s = EmployeeV1.class.getResource("/").getPath(); + String s2 = EmployeeV1.class.getResource("").getPath(); + System.out.println(s); + System.out.println(s2); + + } + + + @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 Exception { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + + byte[] byteCodes = loader.readBinaryCode(className); + + Assert.assertEquals(1030, byteCodes.length); + + } + + + @Test + public void testMagicNumber() throws Exception { + 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 = ByteUtils.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + static ClassFile clzFile = null; + + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + try { + clzFile = loader.loadClass(className); + } catch (IOException e) { + e.printStackTrace(); + } + clzFile.print(); + } + + + @Test + public void testVersion() { + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool() { + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(7); + Assert.assertEquals(44, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(44); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(11); + Assert.assertEquals(48, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(48); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(12); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(13); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(14); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(15); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(16); + Assert.assertEquals("", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(17); + Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(18); + Assert.assertEquals("Code", utf8Info.getValue()); + } + + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(1); + Assert.assertEquals(11, methodRef.getClassInfoIndex()); + Assert.assertEquals(36, methodRef.getNameAndTypeIndex()); + } + + { + NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(36); + Assert.assertEquals(16, nameAndType.getIndex1()); + Assert.assertEquals(28, nameAndType.getIndex2()); + } + //抽查几个吧 + { + MethodRefInfo methodRef = (MethodRefInfo) pool.getConstantInfo(10); + Assert.assertEquals(7, methodRef.getClassInfoIndex()); + Assert.assertEquals(47, methodRef.getNameAndTypeIndex()); + } + + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(35); + 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()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields() { + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + + @Test + public void testMethods() { + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool, m, + "", + "(Ljava/lang/String;I)V", + "2ab700012a2bb500022a1cb50003b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool, m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb50002b1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool, m, + "setAge", + "(I)V", + "2a1bb50003b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool, m, + "sayHello", + "()V", + "b200041205b60006b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool, m, + "main", + "([Ljava/lang/String;)V", + "bb0007591208101db700094c2bb6000ab1"); + } + } + + private void assertMethodEquals(ConstantPool pool, Method m, String expectedName, String expectedDesc, String expectedCode) { + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + +} diff --git a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/EmployeeV1.java b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/EmployeeV1.java similarity index 95% rename from group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/EmployeeV1.java rename to group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/EmployeeV1.java index ab035ac403..3fa9b0fc85 100644 --- a/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/loader/EmployeeV1.java +++ b/group24/1148285693/learning2017/mini-jvm/src/test/java/me/lzb/jvm/EmployeeV1.java @@ -1,4 +1,4 @@ -package me.lzb.loader; +package me.lzb.jvm; public class EmployeeV1 { diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/graph/Graph.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/graph/Graph.java new file mode 100644 index 0000000000..5ef6aba81a --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/graph/Graph.java @@ -0,0 +1,366 @@ +package me.lzb.other.graph; + +import java.util.*; + +/** + * 遍历无向图的所有最长一笔画 + * 深度优先,达到最深时,后退,继续搜索另一条路径 + * Created by LZB on 2017/4/8. + */ +public class Graph { + /** + * 换行符 + */ + private static final String NEWLINE = System.getProperty("line.separator"); + /** + * 路径分割符号 + */ + private static final String PATH_SEPARATOR = "->"; + + /** + * 顶点数目 + */ + private int vertexCount; + + /** + * 边的数目 + */ + private int edgeCount; + + /** + * 出现过路径的最长变数 + * 如果等于总边数,说明存在欧拉路径 + */ + int maxEdge = 0; + + /** + * 顶点数组,每个list是与顶点关联的所有边 + */ + private LinkedList[] edgeList; + + /** + * 边 + */ + private class Edge { + /** + * 边的id + */ + int id; + + /** + * 是否被正向搜索 + */ + boolean isSearched; + + /** + * 顶点v + */ + int v; + + /** + * 顶点b + */ + int w; + + /** + * 保存回滚操作中,被回滚的的路径方向,以及,前提路径 + * 因为在不同级别的回滚中,可能会有多条临时路径,所以用list存放 + * 顶点->顶点:路径id->路径id->路径id + * 1->2:0->1->2 + */ + ArrayList to = new ArrayList<>(); + + /** + * 构造函数 + * @param v 顶点v + * @param w 顶点w + */ + public Edge(int v, int w) { + this.v = v; + this.w = w; + isSearched = false; + id = edgeCount; + } + + + /** + * 在当前前提路径下,是否有 + * @param v0 出发顶点 + * @param P 前提路径 + * @return true false + */ + public boolean isFrom(int v0, String P) { + return isTheSameTo(v0, getAnotherV(v0), P); + } + + /** + * 临时路径是否相同 + * @param v0 出发顶点 + * @param v1 到达顶点 + * @param p 前提路径 + * @return true false + */ + public boolean isTheSameTo(int v0, int v1, String p) { + if (to.size() == 0) { + return false; + } + String ss = v0 + PATH_SEPARATOR + v1 + ":" + p; + for (String s : to) { + if (ss.equals(s)) { + return true; + } + } + return false; + } + + /** + * 删除临时路径 + * @param v0 出发顶点 + * @param v1 到达顶点 + * @param p 前提路径 + */ + public void removeTo(int v0, int v1, String p) { + if (to.size() == 0) { + return; + } + String ss = v0 + PATH_SEPARATOR + v1 + ":" + p; + for (Iterator iterator = to.iterator(); iterator.hasNext(); ) { + String s = iterator.next(); + if (ss.equals(s)) { + iterator.remove(); + return; + } + } + } + + /** + * 增加临时路径 + * @param v0 出发顶点 + * @param v1 到达顶点 + * @param p 前提路径 + */ + public void addTo(int v0, int v1, String p) { + String ss = v0 + PATH_SEPARATOR + v1 + ":" + p; + for (String s : to) { + if (ss.equals(s)) { + return; + } + } + to.add(ss); + + } + + /** + * 获取边的另外一条顶点 + * @param vertex + * @return + */ + public int getAnotherV(int vertex) { + if (vertex == v) { + return w; + } else { + return v; + } + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Edge c = (Edge) obj; + return this.id == c.id; + } + + @Override + public int hashCode() { + return id; + } + } + + /** + * 构造函数 + * @param vertexNum 顶点总数 + * @param edgeCount 边的总数 + */ + public Graph(int vertexNum, int edgeCount) { + this.vertexCount = vertexNum; + this.edgeCount = 0; + edgeList = new LinkedList[edgeCount]; + for (int i = 0; i < edgeCount; i++) { + edgeList[i] = new LinkedList<>(); + } + } + + public void addEdge(int v1, int v2) { + Edge c = new Edge(v2, v1); + edgeList[v1].add(c); + edgeList[v2].add(c); + edgeCount++; + } + + + public void addEdge(int[][] edgeArray) { + for (int i = 0; i < edgeArray.length; i++) { + addEdge(edgeArray[i][0], edgeArray[i][1]); + } + } + + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(vertexCount + " vertices, " + edgeCount + " edges " + NEWLINE); + for (int v = 0; v < vertexCount; v++) { + s.append(v + ": "); + for (Edge w : edgeList[v]) { + s.append(w.getAnotherV(v) + " "); + } + s.append(NEWLINE); + } + return s.toString(); + } + + + /** + * 更新出现过路径的最长边数 + * @param a + */ + private void updateMax(int a) { + if (a > maxEdge) { + maxEdge = a; + } + } + + + public boolean isEuler() { + int start = 0; + Stack stack = new Stack<>(); + stack.push(start); + + //TODO 退出递归的条件 +// try { + search(start, start, stack, new Stack<>()); +// }catch (EmptyStackException e){ + +// } + + System.out.println("最长边数:" + maxEdge); + return maxEdge == edgeCount; + } + + + + + /** + * 正向搜索 + * 传进去一个节点,顺着一条没有搜索过的边找到下一个节点。当搜索到死路时,回滚 + * @param v 当前提点 + * @param stack 当前路径的节点顺序 + * @param sp 当前路径的路径顺序 + */ + public void search(int start, int v, Stack stack, Stack sp) { + + LinkedList list = edgeList[v]; + + boolean anotherWay = false; + for (Edge w : list) { + if (!w.isSearched && !w.isTheSameTo(v, w.getAnotherV(v), getPath(sp))) { + anotherWay = true; + w.isSearched = true; + stack.push(w.getAnotherV(v)); + updateMax(sp.size()); + sp.push(w); + search(start, w.getAnotherV(v), stack, sp); + } + } + + if (!anotherWay) { + System.out.println("最长:==============================="); + rollback(start, stack, sp); + } + + } + + + + /** + * 回滚,回滚当上一个节点,如果当前节点有可以使用的边,调用搜索,如果没有,递归继续回滚 + * 如果需要递归回滚,回滚到第二级之前,清空所有,当前路径下,从该点出发的方向 + * 被回滚的路径,需要保存路径方向,以及提前路径 + * @param stack 当前路径的节点顺序 + * @param sp 当前路径的路径顺序 + */ + public void rollback(int start, Stack stack, Stack sp) { + + String ss = getPath(sp); + String output = "顶点:" + stack.toString() + + NEWLINE + "路径:" + ss + + NEWLINE; + System.out.println(output); + +// if(stack.size() == 1){ +// return; +// } + + + Edge e = sp.pop(); //需要回滚的路径 + String pp = getPath(sp); //前提路径 + + int vz = stack.pop(); + int vy = stack.peek(); + + boolean rollbakc2 = true; + + LinkedList l = edgeList[vy]; + + //判断当前节点是否存在空闲路径,是否要回滚两级 + //空闲路径:没有被正向搜索,也没有被缓存当前前提路径下,从改节点出发的方向 + for (Edge w : l) { + if (!w.isSearched && !w.isTheSameTo(vy, w.getAnotherV(vy), pp)) { + rollbakc2 = false; + break; + } + } + + + //回滚当前路径,回滚一级 + int r = vy; + for (Edge w : l) { + if (w.equals(e)) { + w.addTo(vy, vz, pp); + w.isSearched = false; + break; + } + } + + if (rollbakc2) { + //回滚两级, 清空所有,当前路径下,从该点出发的方向 + + for (Edge w : l) { + if (!w.isSearched && w.isFrom(vy, pp)) { + w.removeTo(vy, w.getAnotherV(vy), pp); + } + } + rollback(start, stack, sp); + } + + search(start, r, stack, sp); + + } + + public String getPath(Stack stack) { + String s = ""; + for (Edge x : stack) { + s = s + x.id + PATH_SEPARATOR; + } + s = s.replaceAll(PATH_SEPARATOR + "$", ""); + return s; + } + + + public static void main(String[] args) { + int[][] aa = new int[][]{{0, 1}, {0, 1}, {0, 3}, {1, 3}, {1, 2}, {1, 2}, {2, 3}}; + Graph g = new Graph(4, aa.length); + g.addEdge(aa); + System.out.println(g.toString()); + System.out.println(g.isEuler()); + } +} diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java new file mode 100644 index 0000000000..4b8b3d4ce8 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest1.java @@ -0,0 +1,27 @@ +package me.lzb.other.lock; + +/** + * Created by LZB on 2017/3/30. + */ +public class ReentrantTest1 implements Runnable{ + + public synchronized void get(){ + System.out.println(Thread.currentThread().getId()); + set(); + } + + public synchronized void set(){ + System.out.println(Thread.currentThread().getId()); + } + + @Override + public void run() { + get(); + } + public static void main(String[] args) { + ReentrantTest1 ss=new ReentrantTest1(); + new Thread(ss).start(); + new Thread(ss).start(); + new Thread(ss).start(); + } +} \ No newline at end of file diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java new file mode 100644 index 0000000000..c630ea9e33 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/lock/ReentrantTest2.java @@ -0,0 +1,35 @@ +package me.lzb.other.lock; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by LZB on 2017/3/30. + */ +public class ReentrantTest2 implements Runnable { + ReentrantLock lock = new ReentrantLock(); + + public void get() { + lock.lock(); + System.out.println(Thread.currentThread().getId()); + set(); + lock.unlock(); + } + + public void set() { + lock.lock(); + System.out.println(Thread.currentThread().getId()); + lock.unlock(); + } + + @Override + public void run() { + get(); + } + + public static void main(String[] args) { + ReentrantTest2 ss = new ReentrantTest2(); + new Thread(ss).start(); + new Thread(ss).start(); + new Thread(ss).start(); + } +} \ No newline at end of file diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java new file mode 100644 index 0000000000..d89298c786 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/MyInvocationHandler.java @@ -0,0 +1,52 @@ +package me.lzb.other.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * Created by LZB on 2017/3/29. + */ +public class MyInvocationHandler implements InvocationHandler { + + // 目标对象 + private Object target; + + /** + * 构造方法 + * + * @param target 目标对象 + */ + public MyInvocationHandler(Object target) { + super(); + this.target = target; + } + + + /** + * 执行目标对象的方法 + */ + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + // 在目标对象的方法执行之前简单的打印一下 + System.out.println("------------------before------------------"); + + // 执行目标对象的方法 + Object result = method.invoke(target, args); + + // 在目标对象的方法执行之后简单的打印一下 + System.out.println("-------------------after------------------"); + + return result; + } + + /** + * 获取目标对象的代理对象 + * + * @return 代理对象 + */ + public Object getProxy() { + return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + target.getClass().getInterfaces(), this); + } +} diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java new file mode 100644 index 0000000000..d57431acab --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserService.java @@ -0,0 +1,11 @@ +package me.lzb.other.proxy; + +/** + * Created by LZB on 2017/3/29. + */ +public interface UserService { + /** + * 目标方法 + */ + void add(); +} diff --git a/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java new file mode 100644 index 0000000000..614b60d9c9 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/main/java/me/lzb/other/proxy/UserServiceImpl.java @@ -0,0 +1,11 @@ +package me.lzb.other.proxy; + +/** + * Created by LZB on 2017/3/29. + */ +public class UserServiceImpl implements UserService { + + public void add() { + System.out.println("--------------------add---------------"); + } +} \ No newline at end of file diff --git a/group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java b/group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java new file mode 100644 index 0000000000..0a01679ad3 --- /dev/null +++ b/group24/1148285693/learning2017/other/src/test/java/me/lzb/other/proxy/ProxyTest.java @@ -0,0 +1,25 @@ +package me.lzb.other.proxy; + +import org.junit.Test; + +/** + * Created by LZB on 2017/3/29. + */ +public class ProxyTest { + + @Test + public void testProxy() throws Throwable { + // 实例化目标对象 + UserService userService = new UserServiceImpl(); + + // 实例化InvocationHandler + MyInvocationHandler invocationHandler = new MyInvocationHandler(userService); + + // 根据目标对象生成代理对象 + UserService proxy = (UserService) invocationHandler.getProxy(); + + // 调用代理对象的方法 + proxy.add(); + + } +} diff --git a/group24/1148285693/learning2017/pom.xml b/group24/1148285693/learning2017/pom.xml index 9b8d948ff9..8dc41781ba 100644 --- a/group24/1148285693/learning2017/pom.xml +++ b/group24/1148285693/learning2017/pom.xml @@ -22,9 +22,10 @@ + common learning-basic mini-jvm - + other @@ -103,6 +104,11 @@ commons-codec 1.10 + + org.apache.commons + commons-collections4 + 4.1 + diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/Stack.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/Stack.java similarity index 63% rename from group24/121111914/src/com/github/ipk2015/coding2017/basic/Stack.java rename to group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/Stack.java index 4dae60e12b..f9c5235e20 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/basic/Stack.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/Stack.java @@ -1,7 +1,9 @@ -package com.github.ipk2015.coding2017.basic; +package com.github.ipk2015.coding2017.basic.stack; import java.util.EmptyStackException; +import com.github.ipk2015.coding2017.basic.ArrayList; + public class Stack { private ArrayList elementData = new ArrayList(); @@ -29,4 +31,12 @@ public boolean isEmpty(){ public int size(){ return elementData.size(); } + public String toString(){ + StringBuffer buffer=new StringBuffer(); + int size=elementData.size(); + for(int i=0;is.size()){ + throw new RuntimeException("len超出范围"); + } + Stack tempStack=new Stack(); + for(int i=0;i0){ + stack.push(flag); + }else if(flag<0){ + if(stack.size()==0){ + return false; + } + Integer peek = (Integer)stack.peek(); + if(peek+flag==0){ + stack.pop(); + }else{ + return false; + } + } + } + if(stack.size()>0){ + return false; + } + return true; + } + private static int switchChar(char c){ + int result=0; + switch(c){ + case '(': + result=1; + break; + case ')': + result=-1; + break; + case '[': + result=2; + break; + case ']': + result=-2; + break; + case '{': + result=3; + break; + case '}': + result=-3; + break; + default: + break; + } + return result; + } + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..61bbe91b2f --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java @@ -0,0 +1,83 @@ +package com.github.ipk2015.coding2017.basic.stack.expr; + +import com.github.ipk2015.coding2017.basic.stack.Stack; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + String[] elements = getElementArray(expr); + + Stack numStack = new Stack(); + Stack operStack = new Stack(); + + manageMultiAndDivOper(elements,numStack,operStack); + + return manageAddAndMinusOper(numStack,operStack); + } + + private void manageMultiAndDivOper(String[] elements,Stack numStack,Stack operStack){ + float preElement,nextElement; + for(int i = 0; i < elements.length;i++){ + if(i%2 == 0){ + numStack.push(Float.valueOf(elements[i])); + }else{ + + if(elements[i].equals("+") || elements[i].equals("-")){ + operStack.push(elements[i]); + }else{ + preElement = (Float)numStack.pop(); + i++; + nextElement = Float.valueOf(elements[i]); + numStack.push(doBaseOper(preElement,nextElement,elements[i-1])); + } + } + } + } + + private float manageAddAndMinusOper(Stack numStack,Stack operStack){ + float result = 0f;; + while(!operStack.isEmpty()){ + result = doBaseOper(result,(Float)numStack.pop(),(String)operStack.pop()); + } + result += (Float)numStack.pop(); + return result; + } + + private float doBaseOper(float preData,float nextData,String oper){ + switch(oper){ + case "+": + return preData+nextData; + case "-": + return preData-nextData; + case "*": + return preData*nextData; + case "/": + return preData/nextData; + default: + throw new RuntimeException("could not recognise oper:"+oper); + } + } + + public String[] getElementArray(String expression){ + char[] charArray = expression.toCharArray(); + StringBuffer stringBuffer = new StringBuffer(); + + for(int i = 0;i items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextUNToInt(2); + int attrLength = iter.nextUNToInt(4); + LineNumberTable lineNumberTable = new LineNumberTable(attrNameIndex,attrLength); + int lineNumTableLen = iter.nextUNToInt(2); + for(int i = 0;i < lineNumTableLen;i++){ + LineNumberItem lineNumberItem = new LineNumberItem(); + lineNumberItem.setStartPC(iter.nextUNToInt(2)); + lineNumberItem.setLineNum(iter.nextUNToInt(2)); + lineNumberTable.addLineNumberItem(lineNumberItem); + } + return lineNumberTable; + } + + + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableItem.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..60f77e5616 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package com.github.ipk2015.coding2017.minijvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableTable.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..3b895ce32e --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/LocalVariableTable.java @@ -0,0 +1,41 @@ +package com.github.ipk2015.coding2017.minijvm.attr; + + +import java.util.ArrayList; +import java.util.List; + + +import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; + + + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextUNToInt(2); + int attrLength = iter.nextUNToInt(4); + LocalVariableTable table = new LocalVariableTable(attrNameIndex,attrLength); + int tableLen = iter.nextUNToInt(2); + for(int i = 0;i < tableLen;i++){ + LocalVariableItem item = new LocalVariableItem(); + item.setStartPC(iter.nextUNToInt(2)); + item.setLength(iter.nextUNToInt(2)); + item.setNameIndex(iter.nextUNToInt(2)); + item.setDescIndex(iter.nextUNToInt(2)); + item.setIndex(iter.nextUNToInt(2)); + table.addLocalVariableItem(item); + } + return table; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/StackMapTable.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/StackMapTable.java new file mode 100644 index 0000000000..b88218c52e --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/StackMapTable.java @@ -0,0 +1,29 @@ +package com.github.ipk2015.coding2017.minijvm.attr; + +import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextUNToInt(2); + int len = iter.nextUNToInt(4); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUNToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/AccessFlag.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/AccessFlag.java new file mode 100644 index 0000000000..138f12d2c7 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/AccessFlag.java @@ -0,0 +1,37 @@ +package com.github.ipk2015.coding2017.minijvm.clz; + + + +public class AccessFlag { + public static int ACC_PUBLIC = 0x0001; + public static int ACC_FINAL = 0x0002; + public static int ACC_SUPER = 0x0020; + public static int ACC_INTEERFACE = 0x0200; + public static int ACC_ABSTRACT = 0x0400; + public static int ACC_SYNTHETIC = 0x1000; + public static int ACC_ANNOTATION = 0x2000; + public static int ACC_ENUM = 0x4000; + + 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 & ACC_PUBLIC) != 0; + } + + public boolean isFinalClass(){ + return (this.flagValue & ACC_FINAL) != 0; + } + +} \ No newline at end of file diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java new file mode 100644 index 0000000000..5cecfc3bff --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java @@ -0,0 +1,92 @@ +package com.github.ipk2015.coding2017.minijvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.field.Field; +import com.github.ipk2015.coding2017.minijvm.method.Method; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + 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 addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + + 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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassIndex.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassIndex.java new file mode 100644 index 0000000000..834863c9ee --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassIndex.java @@ -0,0 +1,21 @@ +package com.github.ipk2015.coding2017.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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java new file mode 100644 index 0000000000..e2e0f50f61 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java @@ -0,0 +1,26 @@ +package com.github.ipk2015.coding2017.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; + } + public int getType() { + return type; + } + + public String getClassName() { + int index = getUtf8Index(); + UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); + return utf8Info.getValue(); + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..663c493b57 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.github.ipk2015.coding2017.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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java new file mode 100644 index 0000000000..ea0e135a23 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.github.ipk2015.coding2017.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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..b74fb427ba --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.github.ipk2015.coding2017.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); + } + 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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..cc5352db6e --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.github.ipk2015.coding2017.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); + } + + 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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..d1cd005111 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.github.ipk2015.coding2017.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; + } + 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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..38eef91f32 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.github.ipk2015.coding2017.minijvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java new file mode 100644 index 0000000000..8f23231e72 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.github.ipk2015.coding2017.minijvm.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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java new file mode 100644 index 0000000000..d94a267bbc --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.github.ipk2015.coding2017.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; + } + 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/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/field/Field.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/field/Field.java new file mode 100644 index 0000000000..7d9b5e1249 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/field/Field.java @@ -0,0 +1,41 @@ +package com.github.ipk2015.coding2017.minijvm.field; + +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + int accessFlag = iter.nextUNToInt(2); + int nameIndex = iter.nextUNToInt(2); + int descriptorIndex = iter.nextUNToInt(2); + int attrCount = iter.nextUNToInt(2); + if(attrCount != 0){ + throw new RuntimeException("字段的属性不为0"); + } + return new Field(accessFlag,nameIndex,descriptorIndex,pool); + } + + public String toString(){ + + return pool.getUTF8String(nameIndex)+":"+pool.getUTF8String(descriptorIndex); + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ByteCodeIterator.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..141331fe4b --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ByteCodeIterator.java @@ -0,0 +1,31 @@ +package com.github.ipk2015.coding2017.minijvm.loader; + +import java.util.Arrays; + +import com.github.ipk2015.coding2017.minijvm.util.Util; + +public class ByteCodeIterator { + private byte[] byteArray; + int pos=0; + + public ByteCodeIterator(byte[] codes){ + this.byteArray=codes; + } + + public int nextUNToInt(int n){ + return Util.byteToInt(nextUNToArray(n)); + } + + public String nextUNToHexString(int n){ + return Util.byteToHexString(nextUNToArray(n)); + } + + public byte[] nextUNToArray(int n){ + byte[] bytes=Arrays.copyOfRange(byteArray, pos, pos+n); + pos=pos+n; + return bytes; + } + public void back(int n) { + this.pos -= n; + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader.java index ab7f54a796..2f854174dd 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader.java @@ -6,67 +6,138 @@ 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; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; + + + + + public class ClassFileLoader { private List clzPaths = new ArrayList(); - public byte[] readBinaryCode(String className) throws IOException { - className=getCompleteClassName(className); - File file=null; - for(String path:clzPaths){ - file=new File(path+"\\"+className); - if(file.exists()){ - break; - } + public byte[] readBinaryCode(String className) { + + 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; + } } - if(null==file){ - throw new FileNotFoundException(className); - } - ByteArrayOutputStream bos=new ByteArrayOutputStream((int)file.length()); - BufferedInputStream in=new BufferedInputStream(new FileInputStream(file)); - int size=1024; - byte[] buffer=new byte[size]; - int length=0; - while((length=in.read(buffer, 0, size))!=-1){ - bos.write(buffer,0,length); + + 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; } - return bos.toByteArray(); } + public void addClassPath(String path) { - clzPaths.add(path); + if(this.clzPaths.contains(path)){ + return; + } + + this.clzPaths.add(path); + } public String getClassPath(){ - StringBuffer buffer=new StringBuffer(); - for(String path:clzPaths){ - buffer.append(path+";"); - } - buffer.deleteCharAt(buffer.length()-1); - return buffer.toString(); + return StringUtils.join(this.clzPaths,";"); } - private String getCompleteClassName(String name){ - if(!name.endsWith(".class")){ - name=name+".class"; + 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-1){ - name=name.substring(pointPos+1); + return buffer.toString(); + } + + private byte[] loadClassFile_V1(String clzFileName) { + + BufferedInputStream bis = null; + + try { + + File f = new File(clzFileName); + + + bis = new BufferedInputStream(new FileInputStream(f)); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + + byte[] buffer = new byte[1024]; + int length = -1; + + while((length = bis.read(buffer)) != -1){ + bos.write(buffer, 0, length); + } + + byte [] codes = bos.toByteArray(); + + return codes; + + } catch(IOException e){ + e.printStackTrace(); + + } finally{ + if(bis != null){ + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } - return name; + return null; + } + -} +} \ No newline at end of file diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader1.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader1.java new file mode 100644 index 0000000000..9879d5a596 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/loader/ClassFileLoader1.java @@ -0,0 +1,125 @@ +package com.github.ipk2015.coding2017.minijvm.loader; + + + +import java.io.BufferedInputStream; +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 ClassFileLoader1 { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + className=getCompleteClassName(className); + File file=null; + for(String path:clzPaths){ + file=new File(path+"\\"+className); + if(file.exists()){ + break; + } + } + if(null==file){ + throw new FileNotFoundException(className); + } + ByteArrayOutputStream bos=new ByteArrayOutputStream((int)file.length()); + BufferedInputStream in=new BufferedInputStream(new FileInputStream(file)); + int size=1024; + byte[] buffer=new byte[size]; + int length=0; + while((length=in.read(buffer, 0, size))!=-1){ + bos.write(buffer,0,length); + } + return bos.toByteArray(); + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath(){ + StringBuffer buffer=new StringBuffer(); + for(String path:clzPaths){ + buffer.append(path+";"); + } + buffer.deleteCharAt(buffer.length()-1); + return buffer.toString(); + } + + private String getCompleteClassName(String name){ + if(!name.endsWith(".class")){ + name=name+".class"; + } + int pointPos=name.lastIndexOf(".", name.length()-7); + if(pointPos>-1){ + name=name.substring(pointPos+1); + } + return name; + } + // ------------------------------backup------------------------ + public String getClassPath_V1(){ + + StringBuffer buffer = new StringBuffer(); + for(int i=0;i parseFields = parseFields(constantPool,iterator); + for(Field f:parseFields){ + classFile.addField(f); + } + + List parseMethods = parseMethods(classFile,iterator); + for(Method m:parseMethods){ + classFile.addMethod(m); + } + + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag flag = new AccessFlag(iter.nextUNToInt(2)); + return flag; + } + + private ClassIndex parseClassInfex(ByteCodeIterator iter) { + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(iter.nextUNToInt(2)); + classIndex.setSuperClassIndex(iter.nextUNToInt(2)); + return classIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int poolSize = iter.nextUNToInt(2); + + ConstantPool pool = new ConstantPool(); + pool.addConstantInfo(new NullConstantInfo()); + + int tag; + for(int i = 1;i < poolSize; i++){ + tag = iter.nextUNToInt(1); + switch(tag){ + case ConstantInfo.CLASS_INFO: + meetClassInfo(pool,iter); + break; + case ConstantInfo.FIELD_INFO: + meetFieldInfo(pool,iter); + break; + case ConstantInfo.METHOD_INFO: + meetMethodInfo(pool,iter); + break; + case ConstantInfo.NAME_AND_TYPE_INFO: + meetNameAndTypeInfo(pool,iter); + break; + case ConstantInfo.STRING_INFO: + meetStringInfo(pool,iter); + break; + case ConstantInfo.UTF8_INFO: + meetUTF8Info(pool,iter); + break; + default: + throw new RuntimeException("还没有关于此的处理,tag:"+tag); + } + } + return pool; + } + + private void meetClassInfo(ConstantPool pool,ByteCodeIterator iter){ + ClassInfo info = new ClassInfo(pool); + info.setUtf8Index(iter.nextUNToInt(2)); + pool.addConstantInfo(info); + } + + private void meetFieldInfo(ConstantPool pool,ByteCodeIterator iter){ + FieldRefInfo info = new FieldRefInfo(pool); + info.setClassInfoIndex(iter.nextUNToInt(2)); + info.setNameAndTypeIndex(iter.nextUNToInt(2)); + pool.addConstantInfo(info); + } + + private void meetMethodInfo(ConstantPool pool,ByteCodeIterator iter){ + MethodRefInfo info = new MethodRefInfo(pool); + info.setClassInfoIndex(iter.nextUNToInt(2)); + info.setNameAndTypeIndex(iter.nextUNToInt(2)); + pool.addConstantInfo(info); + } + + private void meetNameAndTypeInfo(ConstantPool pool,ByteCodeIterator iter){ + NameAndTypeInfo info = new NameAndTypeInfo(pool); + info.setIndex1(iter.nextUNToInt(2)); + info.setIndex2(iter.nextUNToInt(2)); + pool.addConstantInfo(info); + } + + private void meetStringInfo(ConstantPool pool,ByteCodeIterator iter){ + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextUNToInt(2)); + pool.addConstantInfo(info); + } + + private void meetUTF8Info(ConstantPool pool,ByteCodeIterator iter){ + int length = iter.nextUNToInt(2); + byte[] data = iter.nextUNToArray(length); + String value = null; + try { + value=new String(data,"UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info info = new UTF8Info(pool); + info.setLength(length); + info.setValue(value); + pool.addConstantInfo(info); + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextUNToInt(2); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + private List parseFields(ConstantPool pool,ByteCodeIterator iter){ + List list = new ArrayList(); + int count = iter.nextUNToInt(2); + for(int i = 0;i < count;i++){ + list.add(Field.parse(pool, iter)); + } + return list; + } + + private List parseMethods(ClassFile classFile,ByteCodeIterator iter){ + List list = new ArrayList(); + int count = iter.nextUNToInt(2); + for(int i = 0;i < count;i++){ + list.add(Method.parse(classFile, iter)); + } + return list; + } + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java new file mode 100644 index 0000000000..8c08991413 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java @@ -0,0 +1,70 @@ +package com.github.ipk2015.coding2017.minijvm.method; + +import com.github.ipk2015.coding2017.minijvm.attr.AttributeInfo; +import com.github.ipk2015.coding2017.minijvm.attr.CodeAttr; +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + int accessFlag = iter.nextUNToInt(2); + int nameIndex = iter.nextUNToInt(2); + int descriptorIndex = iter.nextUNToInt(2); + Method method = new Method(clzFile,accessFlag,nameIndex,descriptorIndex); + int attrCount = iter.nextUNToInt(2); + for(int i = 0;i < attrCount;i++){ + addAttr(clzFile,method,iter); + } + return method; + } + private static void addAttr(ClassFile clzFile,Method method,ByteCodeIterator iter){ + int nameIndex = iter.nextUNToInt(2); + iter.back(2); + String attrName = clzFile.getConstantPool().getUTF8String(nameIndex); + if(AttributeInfo.CODE.equalsIgnoreCase(attrName)){ + method.setCodeAttr(CodeAttr.parse(clzFile, iter)); + }else{ + throw new RuntimeException("方法的此属性不存在:"+attrName); + } + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java index 61440e39c2..0a3979119d 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java @@ -3,13 +3,24 @@ import java.io.IOException; +import java.util.List; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.minijvm.clz.ClassIndex; +import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.constant.MethodRefInfo; +import com.github.ipk2015.coding2017.minijvm.constant.NameAndTypeInfo; +import com.github.ipk2015.coding2017.minijvm.constant.UTF8Info; +import com.github.ipk2015.coding2017.minijvm.field.Field; import com.github.ipk2015.coding2017.minijvm.loader.ClassFileLoader; +import com.github.ipk2015.coding2017.minijvm.loader.ClassFileLoader1; +import com.github.ipk2015.coding2017.minijvm.method.Method; @@ -23,6 +34,18 @@ public class ClassFileloaderTest { static String path2 = "C:\temp"; static String path3 = "E:\\javaImprove\\git\\group24\\121111914\\src\\com\\github\\ipk2015\\coding2017\\minijvm\\bin"; + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path3); +// String className = "com.coderising.jvm.test.EmployeeV1"; + String className = "EmployeeV1";//老师的class文件单独放在这里,只有类名 + + clzFile = loader.loadClass(className); + clzFile.print(); + } @Before @@ -36,7 +59,7 @@ public void tearDown() throws Exception { @Test public void testClassPath(){ - ClassFileLoader loader = new ClassFileLoader(); + ClassFileLoader1 loader = new ClassFileLoader1(); loader.addClassPath(path1); loader.addClassPath(path2); @@ -47,25 +70,26 @@ public void testClassPath(){ } @Test - public void testClassFileLength() throws IOException { + public void testClassFileLength() { ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path3); - String className = "com.coderising.jvm.test.EmployeeV1"; + String className = "EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); - System.out.println( byteCodes.length+""); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 - Assert.assertEquals(835, byteCodes.length); + Assert.assertEquals(1056, byteCodes.length); } @Test - public void testMagicNumber() throws IOException{ + public void testMagicNumber(){ ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path3); - String className = "com.coderising.jvm.test.EmployeeV1"; + String className = "EmployeeV1"; byte[] byteCodes = loader.readBinaryCode(className); byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; @@ -77,21 +101,183 @@ public void testMagicNumber() throws IOException{ + private 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()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/util/Util.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/util/Util.java new file mode 100644 index 0000000000..b8eaef98ef --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/util/Util.java @@ -0,0 +1,26 @@ +package com.github.ipk2015.coding2017.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 clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws IOException { + String clzFileName = ""; + byte[] byteCodes = null; + boolean classFound = false; + + for (String path : clzPaths) { + clzFileName = path + File.separatorChar + className.replace('.', File.separatorChar) + ".class"; + + if ((byteCodes = loadClassFile(clzFileName)) != null){ + classFound = true; + return byteCodes; + } + } + + if (classFound == false) { + throw new FileNotFoundException(clzFileName); + } + + return null; + } + + private byte[] loadClassFile(String clzFileName) throws IOException { + + File file = new File(clzFileName); + if(!file.exists()){ +// throw new FileNotFoundException(clzFileName); + return null; + } + + ByteArrayOutputStream bos = new ByteArrayOutputStream((int)file.length()); + BufferedInputStream in = null; + + try { + in = new BufferedInputStream(new FileInputStream(file)); + + int buf_size = 1024; + byte[] buffer = new byte[buf_size]; + int len = 0; + + while ((len = in.read(buffer, 0, buf_size)) != -1) { + bos.write(buffer, 0, len); + } + + return bos.toByteArray(); + + } catch (IOException e) { + e.printStackTrace(); + throw e; + } finally { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + bos.close(); + } + } + + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath_V1(){ + + return null; + } + + public String getClassPath(){ + String classPath = ""; + for (int i = 0; i < clzPaths.size(); i++) { + classPath += clzPaths.get(i); + if (i != clzPaths.size() - 1) { + classPath += ";"; + } + } + return classPath; + } + + + +} diff --git a/group24/1525619747/homework_20170402/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group24/1525619747/homework_20170402/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..3192f6596c --- /dev/null +++ b/group24/1525619747/homework_20170402/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,86 @@ +package com.coderising.jvm.test; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + +public class ClassFileloaderTest { + + static String path1 = "F:\\Project\\Java_Project\\Java_SE\\coding2017\\group24\\1525619747\\homework_20170402\\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 = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); +// System.out.println(byteCodes.length); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + System.out.println(byteCodes[0] + " " + byteCodes[1] + " " + byteCodes[2] + " " +byteCodes[3]); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); +// System.out.println(acctualValue); + Assert.assertEquals("cafebabe", acctualValue); + } + + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i 0) { @@ -167,14 +168,6 @@ public Object[] toArray() { return Arrays.copyOf(elementData, size()); } - /** - * A version of rangeCheck used by add and addAll. - */ - private void rangeCheckForAdd(int index) { - if (index > size() - 1 || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } /** * Constructs an IndexOutOfBoundsException detail message. @@ -192,7 +185,7 @@ private String outOfBoundsMsg(int index) { * which throws an ArrayIndexOutOfBoundsException if index is negative. */ private void rangeCheck(int index) { - if (index >= size()) { + if (index < 0 || index >= size()) { throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } } diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrame.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..cdc327fb30 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrame.java @@ -0,0 +1,128 @@ +package com.johnChnia.coding2017.basic.linklist; + +/** + * Created by john on 2017/4/6. + */ +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 pageNum 对象值 + */ + public void access(int pageNum) { + if (first == null) { + Node node = createNode(pageNum); + first = last = node; + capacity--; + } else if (getNode(pageNum) == null) { + if (capacity == 0) { + Node lastNode = first; + while (lastNode.next != null) { + lastNode = lastNode.next; + } + lastNode.prev.next = null; + last = lastNode.prev; + delete(lastNode); + capacity++; + } + Node node = createNode(pageNum); + node.next = first; + node.prev = null; + first.prev = node; + first = node; + capacity--; + + } else { + if (first.pageNum != pageNum) { + Node node = getNode(pageNum); + if (node.next != null) { + node.prev.next = node.next; + node.next.prev = node.prev; + } else { + node.prev.next = null; + last = node.prev; + } + node.next = first; + node.prev = null; + first.prev = node; + first = node; + } + } + + } + + /** + * 删除节点 + */ + private void delete(Node node) { + node.pageNum = 0; + node.next = null; + node.prev = null; + } + + /** + * @param pageNum 页号 + * @return 节点 + */ + private Node createNode(int pageNum) { + Node node = new Node(); + node.pageNum = pageNum; + node.next = null; + node.prev = null; + return node; + } + + + /** + * @param pageNum 页号 + * @return 如果LRUPageFrame包含该pageNum就返回该节点,否则返回null + */ + private Node getNode(int pageNum) { + for (Node node = first; node != null; node = node.next) { + if (node.pageNum == 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/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrameTest.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..e71abd393d --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,30 @@ +package com.johnChnia.coding2017.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/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LinkedList.java similarity index 98% rename from group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java rename to group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LinkedList.java index 01ba928128..10f7edd0a6 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/LinkedList.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/linklist/LinkedList.java @@ -1,4 +1,6 @@ -package com.johnChnia.coding2017.basic; +package com.johnChnia.coding2017.basic.linklist; + +import com.johnChnia.coding2017.basic.List; import java.util.NoSuchElementException; @@ -345,7 +347,7 @@ public int[] getElements(LinkedList list) { valueNode = valueNode.next; indexOfArray++; } else { - mapNode = mapNode.next; + valueNode = valueNode.next; } indexOfList++; } diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/Stack.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/Stack.java similarity index 94% rename from group24/315863321/src/main/java/com/johnChnia/coding2017/basic/Stack.java rename to group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/Stack.java index f43ea52397..c8f1ce7d15 100644 --- a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/Stack.java +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/Stack.java @@ -1,4 +1,6 @@ -package com.johnChnia.coding2017.basic; +package com.johnChnia.coding2017.basic.stack; + +import com.johnChnia.coding2017.basic.linklist.LinkedList; import java.util.EmptyStackException; diff --git a/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/StackUtil.java b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/StackUtil.java new file mode 100644 index 0000000000..4b7c4687d7 --- /dev/null +++ b/group24/315863321/src/main/java/com/johnChnia/coding2017/basic/stack/StackUtil.java @@ -0,0 +1,122 @@ +package com.johnChnia.coding2017.basic.stack; + +/** + * Created by john on 2017/4/7. + */ +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.empty()) { + return; + } + E item = s.pop(); + reverse(s); + insertAtBottom(item, s); + } + + /** + * @param item 插入底部的元素 + * @param s 栈对象引用 + */ + private static void insertAtBottom(E item, Stack s) { + if (s.empty()) { + s.push(item); + } else { + E temp = s.pop(); + insertAtBottom(item, s); + s.push(temp); + } + } + + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s, Object o) { + if (s.empty()) { + return; + } + E item = s.pop(); + if (!o.equals(item)) { //没有考虑o为null的情况 + remove(s, o); + s.push(item); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param len + * @return + */ + public static Object[] getTop(Stack s, int len) { + if (len > s.size()) { + throw new IllegalArgumentException("Len: " + len + ", Size" + s.size()); + } + Object[] array = new Object[len]; + int index = 0; + getArray(s, array, index); + return array; + } + + /** + * 采用递归的方式把len个元素加到数组中,且保持原栈中元素不变。 + * + * @param s 栈 + * @param array Object数组 + * @param index 数组索引 + */ + private static void getArray(Stack s, Object[] array, int index) { + if (s.empty() || index == array.length) { + return; + } + E item = s.pop(); + array[index++] = item; + getArray(s, array, index); + s.push(item); + } + + /** + * 字符串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) { // last unclosed first closed + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + String subStr = s.substring(i, i + 1); + if ("([{".contains(subStr)) { + stack.push(subStr); + } else if (")]}".contains(subStr)) { + if (stack.empty()) { + return false; + } + String left = stack.pop(); + if (subStr.equals(")")) { + if(!left.equals("(")) + return false; + }else if(subStr.equals("]")){ + if(!left.equals("[")) + return false; + }else if(subStr.equals("}")){ + if(!left.equals("{")) + return false; + } + } + } + return stack.empty(); + } + +} \ No newline at end of file diff --git a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/ArrayListTest.java b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/ArrayListTest.java index e0df250c37..4b8d986990 100644 --- a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/ArrayListTest.java +++ b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/ArrayListTest.java @@ -54,7 +54,6 @@ public void testRemoveElementByIndex() { arrayList4.add(i); } Object removed = arrayList4.remove(4); - System.out.println(arrayList4); assertThat(removed, equalTo(4)); assertThat(arrayList4.size(), equalTo(5)); } 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 9a72c0d54a..941d524987 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 @@ -2,7 +2,7 @@ import org.junit.Before; import org.junit.Test; - +import com.johnChnia.coding2017.basic.linklist.LinkedList; import java.util.Arrays; import static org.hamcrest.CoreMatchers.containsString; diff --git a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/StackTest.java b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/StackTest.java index 9d84f7367a..c6f4ec1b2c 100644 --- a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/StackTest.java +++ b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/StackTest.java @@ -1,5 +1,6 @@ package com.johnChnia.coding2017.basic; +import com.johnChnia.coding2017.basic.stack.Stack; import org.junit.Before; import org.junit.Test; diff --git a/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/stack/StackUtilTest.java b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..0a2f277d49 --- /dev/null +++ b/group24/315863321/src/test/java/com/johnChnia/coding2017/basic/stack/StackUtilTest.java @@ -0,0 +1,66 @@ +package com.johnChnia.coding2017.basic.stack; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static com.johnChnia.coding2017.basic.stack.StackUtil.*; + + +/** + * Created by john on 2017/4/7. + */ +public class StackUtilTest { + + Stack s1; + Stack s2; + Stack s3; + + @Before + public void setUp() throws Exception { + s1 = new Stack<>(); + s2 = new Stack<>(); + s3 = new Stack<>(); + + } + + @Test + public void testReverse() throws Exception { + for (int i = 0; i < 4; i++) { + s1.push(i); + } + reverse(s1); + Assert.assertEquals("0→1→2→3", s1.toString()); + } + + @Test + public void testRemove() throws Exception { + for (int i = 0; i < 4; i++) { + s2.push(i); + } + remove(s2, 1); + Assert.assertEquals("3→2→0", s2.toString()); + } + + @Test + public void testGetTop() throws Exception { + for (int i = 0; i < 4; i++) { + s3.push(i); + } + Object[] array = getTop(s3, 2); + Assert.assertEquals(array.length, 2); + Assert.assertEquals(array[0], 3); + Assert.assertEquals(array[1], 2); + Assert.assertEquals("3→2→1→0", s3.toString()); + + } + + @Test + public void testIsValidPairs() throws Exception { + String s1 = "([e{d}f])"; + Assert.assertTrue(isValidPairs(s1)); + String s2 = "([b{x]y})"; + Assert.assertFalse(isValidPairs(s2)); + } + +} \ No newline at end of file diff --git a/group24/330657387/src/main/week01/data_structure/LinkedList.java b/group24/330657387/src/main/week01/data_structure/LinkedList.java index aafe3654ca..3e4053e1da 100644 --- a/group24/330657387/src/main/week01/data_structure/LinkedList.java +++ b/group24/330657387/src/main/week01/data_structure/LinkedList.java @@ -194,7 +194,7 @@ public void removeFirstHalf() { */ public void remove(int i, int length) { rangeCheck(i); - rangeCheck(i + length - 1); + rangeCheck(i + length - 1);//或者当length超出长度,直接认为删除i后面的所有部分。 if (i == 0) { head = getNode(length); size -= length; @@ -216,8 +216,13 @@ public int[] getElements(LinkedList list) throws Exception { if (list == null) { throw new Exception("传入链表为空?"); } + int[] res = new int[list.size]; for (int i = 0; i < list.size; i++) { + //这个list里的值不一定合法的。可以跳过那些不合法的值。 + if(i > size - 1){ + continue; + } res[i] = Integer.parseInt(get( Integer.parseInt(list.get(i).toString()) - 1).toString()); } @@ -298,6 +303,7 @@ public void removeRange(int min, int max) throws Exception { lastRemove = iter.position - 1; } } + //移动指针的时候,注意不要留下指空的指针。不然相关node会无法被gc if(hasmin && firstRemove == 0){ head = getNode(lastRemove); size -= lastRemove-firstRemove+1; @@ -318,44 +324,28 @@ public void removeRange(int min, int max) throws Exception { * @param list */ public LinkedList intersection(LinkedList list) { - if(0 == list.size){ - return this; - } - if(0 == size){ - return list; + if(0 == list.size || 0 == size){ + return new LinkedList(); } + LinkedList res = new LinkedList(); - Node a = head, b = list.head; - while(null != a && null != b){ - if(a.equals(b)){ - res.add(a.data); - a = a.next; - b = b.next; - continue; + Node node1 = this.head; + Node node2 = list.head; + while(node1 != null && node2 != null){ + if((int)node1.data<(int)node2.data){ + node1 = node1.next; + }else if((int)node1.data>(int)node2.data){ + node2 = node2.next; + }else{ + res.add(node1.data); + node1 = node1.next; + node2 = node2.next; } - if(Integer.parseInt(a.data.toString()) > Integer.parseInt(b.data.toString())){ - res.add(b.data); - b = b.next; - continue; - } - if(Integer.parseInt(a.data.toString()) < Integer.parseInt(b.data.toString())){ - res.add(a.data); - a = a.next; - continue; - } - } - while(null != a){ - res.add(a.data); - a = a.next; - } - while(null != b){ - res.add(b.data); - b = b.next; } return res; } - public String ToString() { + public String toString() { LinkedListIterator iter = this.iterator(); StringBuilder sb = new StringBuilder(); while (iter.hasNext()) { diff --git a/group24/330657387/src/main/week01/data_structure/LinkedListTest.java b/group24/330657387/src/main/week01/data_structure/LinkedListTest.java index 671cc20cd2..c0aa471f79 100644 --- a/group24/330657387/src/main/week01/data_structure/LinkedListTest.java +++ b/group24/330657387/src/main/week01/data_structure/LinkedListTest.java @@ -71,14 +71,9 @@ public void testIterator() { public void testReverse() { LinkedList l = lists[2]; l.reverse(); - LinkedListIterator iter = l.iterator(); - StringBuilder sb = new StringBuilder(); - while (iter.hasNext()) { - sb.append(iter.next()); - } // assertEquals("", sb.toString()); - // assertEquals("A", sb.toString()); - assertEquals("EDCBA", sb.toString()); + // assertEquals("A", l.toString()); + assertEquals("E->D->C->B->A->null", l.toString()); } @@ -105,7 +100,7 @@ public void testRemoveByIndex() { try{ LinkedList l = lists[2]; l.remove(0, 1); - System.out.println(l.ToString()); + System.out.println(l.toString()); }catch(Exception e){ assertEquals(IndexOutOfBoundsException.class, e.getClass()); } @@ -155,7 +150,7 @@ public void testSubtract() { l.add(66); try{ list.subtract(l); - System.out.println(list.ToString()); + System.out.println(list.toString()); }catch(Exception e){ assertEquals(e.getMessage(), "传入链表为空?"); } @@ -171,7 +166,7 @@ public void testRemoveDuplicateValues() { list.removeDuplicateValues(); - System.out.println(list.ToString()); + System.out.println(list.toString()); } @Test @@ -185,11 +180,11 @@ public void testRemoveRange() throws Exception { list.add(77); list.add(88); list.add(99); - System.out.println(list.ToString()); + System.out.println(list.toString()); try{ list.removeRange(50, 80); - System.out.println(list.ToString()); + System.out.println(list.toString()); }catch(Exception e){ assertEquals(e.getMessage(), "输入有问题!"); } @@ -208,11 +203,11 @@ public void testIntersection() { // list.add(99); LinkedList l = new LinkedList(); - l.add(10); -// l.add(30); -// l.add(40); -// l.add(60); + l.add(11); + l.add(33); +// l.add(44); +// l.add(66); - System.out.println(list.intersection(l).ToString()); + System.out.println(list.intersection(l).toString()); } } diff --git a/group24/330657387/src/main/week03/download/DownloadThread.java b/group24/330657387/src/main/week03/download/DownloadThread.java index f18bbf234c..37602d1c25 100644 --- a/group24/330657387/src/main/week03/download/DownloadThread.java +++ b/group24/330657387/src/main/week03/download/DownloadThread.java @@ -1,5 +1,6 @@ package main.week03.download; +import java.io.File; import java.io.RandomAccessFile; import java.util.concurrent.CyclicBarrier; @@ -33,7 +34,7 @@ public void run() { + "]"); byte[] data = conn.read(startPos, endPos); - //设置文件的读取权限 + //设置文件的读取权限,每个线程都独立有这个实例,这样,多线程读写同一文件就没问题。 RandomAccessFile file = new RandomAccessFile(localFile, "rw"); file.seek(startPos); @@ -47,9 +48,9 @@ public void run() { barrier.await(); // 等待别的线程完成 } catch (Exception e) { + //如果线程出错了,无法await,怎么处理? e.printStackTrace(); - - } + } finally{}//这块里应该写close的 } } diff --git a/group24/330657387/src/main/week03/download/FileDownloader.java b/group24/330657387/src/main/week03/download/FileDownloader.java index 54d6c260ad..165dc4dfb2 100644 --- a/group24/330657387/src/main/week03/download/FileDownloader.java +++ b/group24/330657387/src/main/week03/download/FileDownloader.java @@ -58,7 +58,7 @@ public void run() { int length = conn.getContentLength(); - //确保文件里有足够的空间? + //确保文件里有足够的空间,就先创建空文件。 createPlaceHolderFile(this.filePath, length); //每个线程的读取区间 diff --git a/group24/330657387/src/main/week03/download/impl/ConnectionImpl.java b/group24/330657387/src/main/week03/download/impl/ConnectionImpl.java index e725ff15a1..e42087d663 100644 --- a/group24/330657387/src/main/week03/download/impl/ConnectionImpl.java +++ b/group24/330657387/src/main/week03/download/impl/ConnectionImpl.java @@ -12,7 +12,8 @@ import main.week03.download.api.Connection; import main.week03.download.api.ConnectionException; -public class ConnectionImpl implements Connection { +//包级可见,是保护措施 +class ConnectionImpl implements Connection { URL url; static final int BUFFER_SIZE = 1024; @@ -29,13 +30,15 @@ public ConnectionImpl(String _url) throws ConnectionException { @Override public byte[] read(int startPos, int endPos) throws IOException { int totalLen = endPos - startPos + 1; - + //是URLConnection的子类,负责http协议的链接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); - InputStream inputStream = conn.getInputStream(); + //客户端可以在请求里放置参数,设置接收数据区间 + //代替了is.skip(),但是is.skip里有read,所以是边读边移动下标的,和本程序意图相违背。 + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + byte[] buffer = new byte[BUFFER_SIZE]; //输出流 diff --git a/group24/330657387/src/main/week03/download/impl/ConnectionManagerImpl.java b/group24/330657387/src/main/week03/download/impl/ConnectionManagerImpl.java index 2253f4fa06..47d5dd22e1 100644 --- a/group24/330657387/src/main/week03/download/impl/ConnectionManagerImpl.java +++ b/group24/330657387/src/main/week03/download/impl/ConnectionManagerImpl.java @@ -4,6 +4,7 @@ import main.week03.download.api.ConnectionException; import main.week03.download.api.ConnectionManager; +//返回接口,是对实现的一种隐蔽 public class ConnectionManagerImpl implements ConnectionManager { @Override diff --git a/group24/330657387/src/main/week03/download/test.jpg b/group24/330657387/src/main/week03/download/test.jpg index 3a052212e5720984b62178e147bd71511578a149..a959a6ad2004f1c27cd2971968ec5abfca97133b 100644 GIT binary patch literal 234626 zcmeIuF%19!0K=fvzv;Qy1rjI>7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* 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%0A{3_1 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 kWCD#p(tCGfWS>lS9d$v-?VBy+C= MAXNSIZE) - throw new RuntimeException(); + throw new RuntimeException("capacitySize : " + capacitySize); } public void clear() { diff --git a/group24/448641125/src/com/donaldy/basic/Stack.java b/group24/448641125/src/com/donaldy/basic/Stack.java index 22fcbbf4bd..ed500638d1 100644 --- a/group24/448641125/src/com/donaldy/basic/Stack.java +++ b/group24/448641125/src/com/donaldy/basic/Stack.java @@ -4,15 +4,15 @@ public class Stack { private ArrayList elementData = new ArrayList(); public void push(Object o) { - elementData.add(o); + this.elementData.add(o); } public Object pop() { - return elementData.remove(size() - 1); + return this.elementData.remove(size() - 1); } public Object peek() { - return elementData.get(size() - 1); + return this.elementData.get(size() - 1); } public boolean isEmpty() { @@ -20,6 +20,6 @@ public boolean isEmpty() { } public int size(){ - return elementData.size(); + return this.elementData.size(); } } diff --git a/group24/448641125/src/com/donaldy/basic/StackUtil.java b/group24/448641125/src/com/donaldy/basic/StackUtil.java new file mode 100644 index 0000000000..ca0014b34e --- /dev/null +++ b/group24/448641125/src/com/donaldy/basic/StackUtil.java @@ -0,0 +1,118 @@ +package com.donaldy.basic; + +import java.util.*; + +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) { + ArrayList arrayList = new ArrayList(); + while (!s.isEmpty()) { + Object element = s.pop(); + arrayList.add(element); + } + + for (int i = 0; i < arrayList.size(); ++i) { + s.push(arrayList.get(i)); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + //若stack的值为唯一的。 + Stack stack = new Stack(); + while (!s.isEmpty()) { + Object element = s.pop(); + if (o == element) { + break; + } + stack.push(element); + } + + while (!stack.isEmpty()) { + Object element = stack.pop(); + s.push(element); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len < 0 || len >= s.size()) + throw new IndexOutOfBoundsException("len : " + len); + + Object [] arr = new Object[len]; + + ArrayList arrayList = new ArrayList(); + + while (!s.isEmpty()) { + arrayList.add(s.pop()); + } + + for (int i = arrayList.size() - 1; i >= 0; --i) + s.push(arrayList.get(i)); + + for (int i = 0 ; i < len; ++i) + arr[i] = arrayList.get(i); + + return arr; + } + /** + * 字符串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){ + char [] arr = s.toCharArray(); + Stack stack = new Stack(); + for (int i = 0; i < s.length(); ++i) { + if (arr[i] == '(' ) + stack.push(')'); + if ( arr[i] == '{' ) + stack.push('}'); + if ( arr[i] == '[') + stack.push(']'); + + if (arr[i] == ')' ) { + if (')' != (char)stack.peek()) + break; + stack.pop(); + } + + if (arr[i] == '}' ) { + if ('}' != (char)stack.peek()) + break; + stack.pop(); + } + + if (arr[i] == ']' ) { + if (']' != (char)stack.peek()) + break; + stack.pop(); + } + + } + + if (stack.isEmpty()) + return true; + + return false; + } + + +} diff --git a/group24/448641125/src/com/donaldy/basic/expr/InfixExpr.java b/group24/448641125/src/com/donaldy/basic/expr/InfixExpr.java new file mode 100644 index 0000000000..dfd901febb --- /dev/null +++ b/group24/448641125/src/com/donaldy/basic/expr/InfixExpr.java @@ -0,0 +1,140 @@ +package com.donaldy.basic.expr; + +import com.donaldy.basic.Stack; + +/** + * 针对最后一个用例,expr: 10 - 30 + 50; + * 负数,直接对后面的数进行取反(实际上计算机就是这样做的,组原有提。) + * 即:expr: 10 - 30 + 50 + * 处理后: 10 + -30 + 50 + */ +public class InfixExpr { + + String expr = null; + + Stack numStack = new Stack(); + Stack symbolStack = new Stack(); + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + if (!this.numStack.isEmpty()) + return (float) this.numStack.peek(); + + char [] arr = this.expr.toCharArray(); + + parseCharArray(arr); + + remainOperate(); + + return (float) this.numStack.peek(); + } + + private void parseCharArray(char [] arr) { + + for (int i = 0; i < arr.length; ) { + + i = parseNumberReturnIndex(i, arr); + + if (i >= arr.length) + break; + + i = parseSymbolReturnIndex(i, arr); + } + } + + private int parseNumberReturnIndex(int index, char [] arr) { + if (arr[index] <= '9' && arr[index] >= '0' ) { + + float value = arr[index ++] - '0'; + + while (index < arr.length && arr[index] <= '9' && arr[index] >= '0' ) { + value *= 10; + value += arr[index] - '0'; + index ++; + } + this.numStack.push(value); + } + + return index; + } + + private int parseSymbolReturnIndex(int index, char[] arr) { + + if ("+-*/".contains(arr[index] + "")) { + + char operator = arr[index ++]; + + if (operator == '+') { + this.symbolStack.push('+'); + } + + if (operator == '-') { + + this.symbolStack.push('+'); + + float value = arr[index ++] - '0'; + + while (index < arr.length && arr[index] <= '9' && arr[index] >= '0') { + value *= 10; + value += arr[index] - '0'; + index ++; + } + + this.numStack.push(-value); + } + + if (operator == '*' || operator == '/') { + + float value1 = (float) this.numStack.pop(); + float value2 = arr[index ++] - '0'; + + while (index < arr.length && arr[index] <= '9' && arr[index] >= '0') { + value2 *= 10; + value2 += arr[index] - '0'; + index ++; + } + + this.numStack.push(operate(value2, value1, operator)); + + } + + } + + return index; + } + + private void remainOperate() { + while (!this.symbolStack.isEmpty()) { + if (this.numStack.size() < 2 || this.symbolStack.size() < 1) + throw new IndexOutOfBoundsException("numStack.size : " + this.numStack.size() + + " symbolStack.size : " + this.symbolStack.size()); + + float value1 = (float) this.numStack.pop(); + float value2 = (float) this.numStack.pop(); + char cSymbol = (char) this.symbolStack.pop(); + + this.numStack.push(operate(value1, value2, cSymbol)); + } + } + + + private float operate (float value1, float value2, char operator) { + + if (operator == '+') { + return value2 + value1; + } else if (operator == '*') { + return value2 * value1; + } else if (operator == '/') { + return value2 / value1; + } else { + throw new RuntimeException("No this operator : " + operator); + } + + } + + +} diff --git a/group24/448641125/src/com/donaldy/basic/expr/InfixExprTest.java b/group24/448641125/src/com/donaldy/basic/expr/InfixExprTest.java new file mode 100644 index 0000000000..47afcec569 --- /dev/null +++ b/group24/448641125/src/com/donaldy/basic/expr/InfixExprTest.java @@ -0,0 +1,48 @@ +package com.donaldy.basic.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group24/448641125/src/com/donaldy/jvm/attr/AttributeInfo.java b/group24/448641125/src/com/donaldy/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..db2cdc8f97 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.donaldy.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} diff --git a/group24/448641125/src/com/donaldy/jvm/attr/CodeAttr.java b/group24/448641125/src/com/donaldy/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..6b699e6991 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/attr/CodeAttr.java @@ -0,0 +1,56 @@ +package com.donaldy.jvm.attr; + +import com.donaldy.jvm.clz.ClassFile; +import com.donaldy.jvm.constant.ConstantPool; +import com.donaldy.jvm.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + + + return null; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/group24/448641125/src/com/donaldy/jvm/attr/LineNumberTable.java b/group24/448641125/src/com/donaldy/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..9dc9ab1dc9 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/attr/LineNumberTable.java @@ -0,0 +1,57 @@ +package com.donaldy.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.donaldy.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List items = new ArrayList(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + int attributeLen = iter.nextU4ToInt(); + int lnTableLen = iter.nextU2ToInt(); + LineNumberTable lnTable = new LineNumberTable(attrNameIndex, attributeLen); + + System.out.println("LineNumberTable.lnTableLen : " + lnTableLen); + + for (int i = 0; i < lnTableLen; ++i) { + LineNumberItem lnItem = new LineNumberItem(); + + lnItem.setStartPC(iter.nextU2ToInt()); + lnItem.setLineNum(iter.nextU2ToInt()); + + lnTable.addLineNumberItem(lnItem); + } + + return lnTable; + } + + + +} diff --git a/group24/448641125/src/com/donaldy/jvm/attr/LocalVariableItem.java b/group24/448641125/src/com/donaldy/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..7f04ebbc22 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package com.donaldy.jvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/group24/448641125/src/com/donaldy/jvm/attr/LocalVariableTable.java b/group24/448641125/src/com/donaldy/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..c207540570 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/attr/LocalVariableTable.java @@ -0,0 +1,45 @@ +package com.donaldy.jvm.attr; + + +import java.util.ArrayList; +import java.util.List; + +import com.donaldy.jvm.constant.ConstantPool; + +import com.donaldy.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List items = new ArrayList(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + int attrNameIndex = iter.nextU2ToInt(); + int attrLen = iter.nextU4ToInt(); + int localVariableTableLen = iter.nextU2ToInt(); + + LocalVariableTable lvTable = new LocalVariableTable(attrNameIndex, attrLen); + + for (int i = 0 ; i < localVariableTableLen; ++i) { + LocalVariableItem lvItem = new LocalVariableItem(); + lvItem.setStartPC(iter.nextU2ToInt()); + lvItem.setLength(iter.nextU2ToInt()); + lvItem.setNameIndex(iter.nextU2ToInt()); + lvItem.setDescIndex(iter.nextU2ToInt()); + lvItem.setIndex(iter.nextU2ToInt()); + + lvTable.addLocalVariableItem(lvItem); + } + + + return lvTable; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/group24/448641125/src/com/donaldy/jvm/attr/StackMapTable.java b/group24/448641125/src/com/donaldy/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..41365dc049 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/attr/StackMapTable.java @@ -0,0 +1,30 @@ +package com.donaldy.jvm.attr; + + +import com.donaldy.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group24/448641125/src/com/donaldy/jvm/clz/AccessFlag.java b/group24/448641125/src/com/donaldy/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..ea06ad07cb --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/clz/ClassFile.java b/group24/448641125/src/com/donaldy/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..c36e1940b1 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/clz/ClassFile.java @@ -0,0 +1,92 @@ +package com.donaldy.jvm.clz; + +import com.donaldy.jvm.constant.ClassInfo; +import com.donaldy.jvm.constant.ConstantPool; +import com.donaldy.jvm.field.Field; +import com.donaldy.jvm.method.Method; + +import java.util.ArrayList; +import java.util.List; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List fields = new ArrayList(); + private List methods = new ArrayList(); + + 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 addField(Field f){ + this.fields.add(f); + } + public List getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List getMethods() { + return methods; + } + + + 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/group24/448641125/src/com/donaldy/jvm/clz/ClassIndex.java b/group24/448641125/src/com/donaldy/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..d7e0524060 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/ClassInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..71f31261e4 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/ConstantInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..20cad6fcd5 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/ConstantPool.java b/group24/448641125/src/com/donaldy/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..77bdfc8e67 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/ConstantPool.java @@ -0,0 +1,29 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/FieldRefInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..6a6f72f5da --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/MethodRefInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..e65135279f --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/NameAndTypeInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..21ecd2b411 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/NullConstantInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..3a2cc11017 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.donaldy.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group24/448641125/src/com/donaldy/jvm/constant/StringInfo.java b/group24/448641125/src/com/donaldy/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..f59d34a497 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/constant/UTF8Info.java b/group24/448641125/src/com/donaldy/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..7432e5b6c4 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.donaldy.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/group24/448641125/src/com/donaldy/jvm/field/Field.java b/group24/448641125/src/com/donaldy/jvm/field/Field.java new file mode 100644 index 0000000000..18cad5669a --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/field/Field.java @@ -0,0 +1,46 @@ +package com.donaldy.jvm.field; + +import com.donaldy.jvm.constant.ConstantPool; +import com.donaldy.jvm.constant.UTF8Info; +import com.donaldy.jvm.loader.ByteCodeIterator; + + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + private ConstantPool pool; + + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + + int accessFlag = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptorIndex = iter.nextU2ToInt(); + + //TODO : 因无static类型变量,所以这无 + int attributesCount = iter.nextU2ToInt(); + + Field file = new Field(accessFlag, nameIndex, descriptorIndex, pool); + + return file; + } + + public String toString() { + //System.out.println("name : " + this.nameIndex + ", desc : " + descriptorIndex); + String description = this.pool.getUTF8String(this.descriptorIndex); + String name = this.pool.getUTF8String(this.nameIndex); + return name + ":"+ description; + } +} diff --git a/group24/448641125/src/com/donaldy/jvm/loader/ByteCodeIterator.java b/group24/448641125/src/com/donaldy/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..82eae449b9 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,104 @@ +package com.donaldy.jvm.loader; + +import com.donaldy.jvm.util.Util; + +import java.util.Arrays; + +public class ByteCodeIterator { + + byte[] codes; + int pos = 0; + + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1toInt() { + + return Util.byteToInt(new byte[] { codes[pos++] }); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++] }); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }); + } + + public String nextU4ToHexString() { + return Util.byteToHexString((new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] })); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + + } + + public void back(int n) { + this.pos -= n; + } + + ///////////////////////Backup////////////////// + /*private byte[] codes; + + private int pointer = 0; + + public ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + public String nextU4ToHexString() { + byte [] byteCodes = nextLenByte(4); + + return Util.byteToHexString(byteCodes); + } + + public int nextU2ToInt() { + byte [] byteCodes = nextLenByte(2); + + return Util.byteToInt(byteCodes); + } + + public int nextU1toInt() { + byte [] byteCodes = nextLenByte(1); + + return Util.byteToInt(byteCodes); + } + + public byte[] getBytes(int len) { + byte [] byteCodes = nextLenByte(len); + + return byteCodes; + } + + private byte[] nextLenByte(int len) { + if (this.pointer + len >= this.codes.length) + throw new IndexOutOfBoundsException("codes.length : " + this.codes.length); + + byte [] byteCodes = new byte[len]; + + for (int i = 0 ; i < len; ++i) { + byteCodes[i] = this.codes[pointer ++]; + } + + return byteCodes; + }*/ +} diff --git a/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java b/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java index c4a64b26d6..e1132dd023 100644 --- a/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java +++ b/group24/448641125/src/com/donaldy/jvm/loader/ClassFileLoader.java @@ -2,7 +2,10 @@ import java.io.*; import java.util.ArrayList; -import java.util.Iterator; + +import com.donaldy.jvm.clz.ClassFile; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import java.util.List; @@ -12,15 +15,69 @@ public class ClassFileLoader { private List clzPaths = new ArrayList(); static final int BUFFER_SIZE = 1024; - + public byte[] readBinaryCode(String className) { + className = className.replace(".", File.separator) + ".class"; + + for (String path : this.clzPaths) { + + String clzFileName = path + File.separator + 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 StringUtils.join(this.clzPaths, ";"); + } + + public ClassFile loadClass(String className) { + byte[] codes = this.readBinaryCode(className); + ClassFileParser parser = new ClassFileParser(); + return parser.parse(codes); + + } + + + + + + ////////////////////////////////Backup/////////////////////////////// + public byte[] readBinaryCode_V1(String className) { + for (String clzPath : clzPaths) { File file = new File(clzPath + className.replace(".", "\\") + ".class"); - + if (!file.exists()) continue; @@ -52,24 +109,17 @@ public byte[] readBinaryCode(String className) { } - - public void addClassPath(String path) { - if (path == null) - return; - - clzPaths.add(path); - } - - - - public String getClassPath(){ + public String getClassPath_V1(){ StringBuilder sb = new StringBuilder(); - int length = clzPaths.size(); + + int length = this.clzPaths.size(); + for (int i = 0 ; i < length; ++i) { - sb.append(clzPaths.get(i)); + sb.append(this.clzPaths.get(i)); if (i + 1 < length) sb.append(";"); } + return sb.toString(); } diff --git a/group24/448641125/src/com/donaldy/jvm/loader/ClassFileParser.java b/group24/448641125/src/com/donaldy/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..b0229c7435 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/loader/ClassFileParser.java @@ -0,0 +1,166 @@ +package com.donaldy.jvm.loader; + +import com.donaldy.jvm.clz.AccessFlag; +import com.donaldy.jvm.clz.ClassFile; +import com.donaldy.jvm.clz.ClassIndex; +import com.donaldy.jvm.constant.*; +import com.donaldy.jvm.field.Field; +import com.donaldy.jvm.method.Method; + +import java.io.UnsupportedEncodingException; + + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + + ByteCodeIterator iter = new ByteCodeIterator(codes); + ClassFile clzFile = new ClassFile(); + + String magicNumber = iter.nextU4ToHexString(); + + if (!"cafebabe".equals(magicNumber)) { + return null; + } + + clzFile.setMinorVersion(iter.nextU2ToInt()); + clzFile.setMajorVersion(iter.nextU2ToInt()); + + ConstantPool pool = parseConstantPool(iter); + clzFile.setConstPool(pool); + + AccessFlag flag = parseAccessFlag(iter); + clzFile.setAccessFlag(flag); + + ClassIndex clzIndex = parseClassIndex(iter); + clzFile.setClassIndex(clzIndex); + + ////////////Third times JVM homework//////////// + parseInterfaces(iter); //本次作业无interface + + parseFileds(clzFile, iter); + + parseMethods(clzFile, iter); + + return clzFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + AccessFlag flag = new AccessFlag(iter.nextU2ToInt()); + return flag; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + + int thisClassIndex = iter.nextU2ToInt(); + + int superClassIndex = iter.nextU2ToInt(); + + ClassIndex clzIndex = new ClassIndex(); + + clzIndex.setThisClassIndex(thisClassIndex); + + clzIndex.setSuperClassIndex(superClassIndex); + + return clzIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constPoolCount = iter.nextU2ToInt(); + + System.out.println("Constant Pool Count : " + constPoolCount); + + ConstantPool pool = new ConstantPool(); + + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i <= constPoolCount - 1; ++i) { + + int tag = iter.nextU1toInt(); + + if (tag == 7) { + //Class Info + int utf8Index = iter.nextU2ToInt(); + ClassInfo clzInfo = new ClassInfo(pool); + clzInfo.setUtf8Index(utf8Index); + + pool.addConstantInfo(clzInfo); + } else if (tag == 1) { + //UTF-8 String + int len = iter.nextU2ToInt(); + byte [] data = iter.getBytes(len); + String value = null; + try { + value = new String(data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info utf8Info = new UTF8Info(pool); + utf8Info.setLength(len); + utf8Info.setValue(value); + pool.addConstantInfo(utf8Info); + } else if (tag == 8) { + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(info); + } else if (tag == 9) { + FieldRefInfo field = new FieldRefInfo(pool); + field.setClassInfoIndex(iter.nextU2ToInt()); + field.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(field); + + } else if (tag == 10) { + //MethodRef + MethodRefInfo method = new MethodRefInfo(pool); + method.setClassInfoIndex(iter.nextU2ToInt()); + method.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(method); + } else if (tag == 12) { + // Name and Type Info + NameAndTypeInfo nameType = new NameAndTypeInfo(pool); + nameType.setIndex1(iter.nextU2ToInt()); + nameType.setIndex2(iter.nextU2ToInt()); + pool.addConstantInfo(nameType); + } else { + throw new RuntimeException("the constant pool tag" + tag); + } + } + + return pool; + } + + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextU2ToInt(); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + private void parseFileds(ClassFile clzFile, ByteCodeIterator iter) { + int fieldCount = iter.nextU2ToInt(); + + //System.out.println("fileCount : " + fieldCount); + + for (int i = 1; i <= fieldCount; i++) { + Field f = Field.parse(clzFile.getConstantPool(), iter); + clzFile.addField(f); + } + + } + + private void parseMethods(ClassFile clzFile, ByteCodeIterator iter) { + + int methodCount = iter.nextU2ToInt(); + + for (int i = 1; i <= methodCount; i++) { + Method m = Method.parse(clzFile, iter); + clzFile.addMethod(m); + } + + } + +} diff --git a/group24/448641125/src/com/donaldy/jvm/method/Method.java b/group24/448641125/src/com/donaldy/jvm/method/Method.java new file mode 100644 index 0000000000..a69ff696b8 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/method/Method.java @@ -0,0 +1,89 @@ +package com.donaldy.jvm.method; + +import com.donaldy.jvm.attr.*; +import com.donaldy.jvm.clz.ClassFile; +import com.donaldy.jvm.constant.ConstantPool; +import com.donaldy.jvm.constant.UTF8Info; +import com.donaldy.jvm.loader.ByteCodeIterator; + + + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + + int accessFlag = iter.nextU2ToInt(); + int nameIndex = iter.nextU2ToInt(); + int descriptorIndex = iter.nextU2ToInt(); + + int attributeCount = iter.nextU2ToInt(); + System.out.println("attributeCount : " + attributeCount); + + int attrNameIndex = iter.nextU2ToInt(); + if (!"Code".equals(clzFile.getConstantPool().getUTF8String(attrNameIndex))) + throw new RuntimeException("attributeInfo : " + attrNameIndex); + + int attrLen = iter.nextU4ToInt(); + int maxStack = iter.nextU2ToInt(); + int maxLocals = iter.nextU2ToInt(); + int codeLen = iter.nextU4ToInt(); + String code = iter.nextUxToHexString(codeLen); + + CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code); + + int exceptionLen = iter.nextU2ToInt(); + System.out.println("execptionLen : " + exceptionLen); + + int attributesCount = iter.nextU2ToInt(); + System.out.println("attributeCount : " + attributesCount); + + LineNumberTable lnTable = LineNumberTable.parse(iter); + codeAttr.setLineNumberTable(lnTable); + + LocalVariableTable lvTable = LocalVariableTable.parse(iter); + codeAttr.setLocalVariableTable(lvTable); + + + Method method = new Method(clzFile, accessFlag, nameIndex, descriptorIndex); + + method.setCodeAttr(codeAttr); + return method; + + } +} diff --git a/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java b/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java index 2ed50aa8b5..8610fda4c9 100644 --- a/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java +++ b/group24/448641125/src/com/donaldy/jvm/test/ClassFileloaderTest.java @@ -1,5 +1,10 @@ package com.donaldy.jvm.test; +import com.donaldy.jvm.clz.ClassFile; +import com.donaldy.jvm.clz.ClassIndex; +import com.donaldy.jvm.constant.*; +import com.donaldy.jvm.field.Field; +import com.donaldy.jvm.method.Method; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -7,17 +12,17 @@ import com.donaldy.jvm.loader.ClassFileLoader; - - +import java.util.List; public class ClassFileloaderTest { - + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + static String path1 = "D:\\tools\\Code\\Y_Repository\\coding2017\\group24\\448641125\\out\\production\\448641125\\"; static String path2 = "C:\\temp"; - - + + static ClassFile clzFile = null; @Before public void setUp() throws Exception { @@ -69,10 +74,7 @@ public void testMagicNumber(){ Assert.assertEquals("cafebabe", acctualValue); } - - - - + private String byteToHexString(byte[] codes ){ @@ -89,4 +91,189 @@ private String byteToHexString(byte[] codes ){ return buffer.toString(); } + + /** + * ---------------------------------------------------------------------- + */ + + + @Test + public void testVersion(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(this.path1); + clzFile = loader.loadClass("com.donaldy.jvm.test.EmployeeV1"); + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(this.path1); + clzFile = loader.loadClass("com.donaldy.jvm.test.EmployeeV1"); + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); + } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("", 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(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(this.path1); + clzFile = loader.loadClass("com.donaldy.jvm.test.EmployeeV1"); + + 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()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(this.path1); + clzFile = loader.loadClass("com.donaldy.jvm.test.EmployeeV1"); + + List fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(this.path1); + clzFile = loader.loadClass("com.donaldy.jvm.test.EmployeeV1"); + + + List methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + } diff --git a/group24/448641125/src/com/donaldy/jvm/util/Util.java b/group24/448641125/src/com/donaldy/jvm/util/Util.java new file mode 100644 index 0000000000..f316117565 --- /dev/null +++ b/group24/448641125/src/com/donaldy/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.donaldy.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= 0 ; --i) + stack.push(intArr[i]); + StackUtil.reverse(stack); + for (int i = 4 ; i >= 0; --i) { + Assert.assertEquals((int)stack.pop(), (int)intArr[i]); + } + } + + @Test + public void testRemove() { + Stack stack = new Stack(); + Integer [] intArr = {5, 4, 3, 2, 1}; + for (int i = 4; i >= 0 ; --i) + stack.push(intArr[i]); + + StackUtil.remove(stack, 2); + for (int i = 0; i < 5; ++i) { + if (i == 3) + continue; + System.out.println("stack: " + stack.peek() + " i : " + (int) intArr[i]); + Assert.assertEquals((int)stack.pop(), (int)intArr[i]); + } + } + + @Test + public void testGetTop() { + Stack stack = new Stack(); + Integer [] intArr = {5, 4, 3, 2, 1}; + for (int i = 4; i >= 0 ; --i) + stack.push(intArr[i]); + + int len = 3; + Object [] arr = StackUtil.getTop(stack, len); + + for (int i = 0 ; i < arr.length ; ++i) { + Assert.assertEquals((int)arr[i], (int)intArr[i]); + } + + for (int i = 0; i < 5; ++i) { + Assert.assertEquals((int)intArr[i], (int)stack.pop()); + } + } + + @Test + public void testIsValidPairs() { + + String str1 = "([e{d}f])"; + Assert.assertEquals(true, StackUtil.isValidPairs(str1)); + + String str2 = "([b{x]y})"; + Assert.assertEquals(false, StackUtil.isValidPairs(str2)); + + } +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/AccessFlag.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..0dedb245ee --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassFile.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..0d2525e416 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,76 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.clz; + + +import com.coding.mini_jvm.src.com.coderising.jvm.constant.ClassInfo; +import com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassIndex.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..4dc110fe5f --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ClassInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..227bb010a1 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..e7c849ca59 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantPool.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..d4210647be --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/ConstantPool.java @@ -0,0 +1,36 @@ +package com.coding.mini_jvm.src.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; + } + + @Override + public String toString() { + return "ConstantPool{" + + "constantInfos=" + constantInfos + + '}'; + } +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/FieldRefInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..1808a35c65 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/MethodRefInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..dc62d438e6 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..b8b9da7353 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NullConstantInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..bf19f681d8 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/StringInfo.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..05a4afad6a --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/UTF8Info.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..61f20ed8f1 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package com.coding.mini_jvm.src.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/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..27d0c63af0 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,52 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.loader; + +import com.coding.mini_jvm.src.com.coderising.jvm.util.Util; + +public class ByteCodeIterator { + private static final int U1 = 1; + private static final int U2 = 2; + private static final int U4 = 4; + private static final int U8 = 8; + private byte[] bytes; + private int cursor; + + public ByteCodeIterator(byte[] bytes) { + this.bytes = bytes; + } + + public String readTwoBytesToString() { + String ret = Util.byte2String(bytes, cursor, U2); + cursor += U2; + return ret; + } + + public String readBytesToString(int len) { + String ret = Util.byte2String(bytes, cursor, len); + cursor += len; + return ret; + } + + + public int readTwoBytesToInt() { + int ret = Util.bytes2Int(bytes, cursor, U2); + cursor += U2; + return ret; + } + + public int readByteToInt() { + int ret = Util.bytes2Int(bytes, cursor, U1); + cursor += U1; + return ret; + } + + + + + public int skip(int len) { + if (cursor + len < 0 || cursor + len > bytes.length - 1) { + throw new IndexOutOfBoundsException(); + } + cursor += len; + return cursor; + } +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java index 1ca7cc8ece..452f6bce7d 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -1,6 +1,11 @@ package com.coding.mini_jvm.src.com.coderising.jvm.loader; -import java.io.*; +import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -14,29 +19,35 @@ public class ClassFileLoader { public byte[] readBinaryCode(String className) { String classPath = getClassPath(); String[] paths = classPath.split(File.pathSeparator); - className = className.replaceAll("\\.", "\\"+File.separator) ; + className = className.replace('.', File.separatorChar) ; for (String path : paths) { - String filename = path + File.separator + className + CLASS_FILE_SUFFIX; - File file = new File(filename); - if (file.exists()) { - try { - FileInputStream fis = new FileInputStream(file); - BufferedInputStream bis = new BufferedInputStream(fis); - byte[] data = new byte[bis.available()]; - bis.read(data); - return data; - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + String clzFilename = path + File.separator + className + CLASS_FILE_SUFFIX; + byte[] data = loadClassFile(clzFilename); + if (data != null) { + return data; } } return null; } - + + private byte[] loadClassFile(String clzFileName) { + File file = new File(clzFileName); + BufferedInputStream bis = null; + try { + bis = new BufferedInputStream(new FileInputStream(file)); + byte[] data = new byte[bis.available()]; + bis.read(data); + return data; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } public void addClassPath(String path) { + if (this.clzPaths.contains(path)) { + return; + } clzPaths.add(path); } @@ -52,8 +63,10 @@ public String getClassPath(){ return path.substring(0, path.lastIndexOf(";")); } - - - + public ClassFile loadClass(String className) { + byte[] data = readBinaryCode(className); + ClassFileParser classFileParser = new ClassFileParser(); + return classFileParser.parse(data); + } } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileParser.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..542968c809 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,103 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.loader; + +import com.coding.mini_jvm.src.com.coderising.jvm.clz.AccessFlag; +import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; +import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassIndex; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.*; + + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ClassFile classFile = new ClassFile(); + ByteCodeIterator iterator = new ByteCodeIterator(codes); + //跳过魔数 + iterator.skip(4); + //次版本号 + classFile.setMinorVersion(iterator.readTwoBytesToInt()); + //主版本号 + classFile.setMajorVersion(iterator.readTwoBytesToInt()); + //解析常量池 + classFile.setConstPool(parseConstantPool(iterator)); + //访问限制符 + classFile.setAccessFlag(parseAccessFlag(iterator)); + //当前类/父类 + classFile.setClassIndex(parseClassIndex(iterator)); + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + return new AccessFlag(iter.readTwoBytesToInt()); + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + ClassIndex classIndex = new ClassIndex(); + classIndex.setThisClassIndex(iter.readTwoBytesToInt()); + classIndex.setSuperClassIndex(iter.readTwoBytesToInt()); + return classIndex; + } + + private ConstantPool parseConstantPool(ByteCodeIterator iterator) { + ConstantPool constantPool = new ConstantPool(); + //读取常量个数 + int constantPoolCount = iterator.readTwoBytesToInt(); + constantPool.addConstantInfo(new NullConstantInfo()); + for (int i = 1; i < constantPoolCount; i++) { + int flag = iterator.readByteToInt(); + int utf8Index; + int clzIndex; + int nameAndTypeIndex; + switch (flag) { + case 1: + int length = iterator.readTwoBytesToInt(); + String val = iterator.readBytesToString(length); + UTF8Info utf8Info = new UTF8Info(constantPool); + utf8Info.setLength(length); + utf8Info.setValue(val); + constantPool.addConstantInfo(utf8Info); + break; + case 7: + utf8Index = iterator.readTwoBytesToInt(); + ClassInfo classInfo = new ClassInfo(constantPool); + classInfo.setUtf8Index(utf8Index); + constantPool.addConstantInfo(classInfo); + break; + case 8: + utf8Index = iterator.readTwoBytesToInt(); + StringInfo stringInfo = new StringInfo(constantPool); + stringInfo.setIndex(utf8Index); + constantPool.addConstantInfo(stringInfo); + break; + case 9: + clzIndex = iterator.readTwoBytesToInt(); + nameAndTypeIndex = iterator.readTwoBytesToInt(); + FieldRefInfo fieldRefInfo = new FieldRefInfo(constantPool); + fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + fieldRefInfo.setClassInfoIndex(clzIndex); + constantPool.addConstantInfo(fieldRefInfo); + break; + case 10: + clzIndex = iterator.readTwoBytesToInt(); + nameAndTypeIndex = iterator.readTwoBytesToInt(); + MethodRefInfo methodRefInfo = new MethodRefInfo(constantPool); + methodRefInfo.setClassInfoIndex(clzIndex); + methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex); + constantPool.addConstantInfo(methodRefInfo); + break; + case 12: + utf8Index = iterator.readTwoBytesToInt(); + int utf8Index1 = iterator.readTwoBytesToInt(); + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(constantPool); + nameAndTypeInfo.setIndex1(utf8Index); + nameAndTypeInfo.setIndex2(utf8Index1); + constantPool.addConstantInfo(nameAndTypeInfo); + break; + default: + throw new RuntimeException("flag "+ flag +" is not exists"); + } + } + return constantPool; + } + + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/util/Util.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/util/Util.java new file mode 100644 index 0000000000..8811e3541c --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/util/Util.java @@ -0,0 +1,40 @@ +package com.coding.mini_jvm.src.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 int bytes2Int(byte[] b, int start, int len) { + int sum = 0; + int end = start + len; + for (int i = start; i < end; i++) { + int n = ((int) b[i]) & 0xff; + n <<= (--len) * 8; + sum = n + sum; + } + return sum; + } + + + public static String byte2String(byte[] b, int start, int len) { + return new String(b, start, len); + } + + public static String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i= 0; i--) { + sb.append(elementData.get(i).toString()); + sb.append(","); + } + return sb.substring(0, sb.lastIndexOf(",")); + } } diff --git a/group24/494800949/src/main/java/com/coding/week5/stack/StackUtil.java b/group24/494800949/src/main/java/com/coding/week5/stack/StackUtil.java new file mode 100644 index 0000000000..7b750b3549 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week5/stack/StackUtil.java @@ -0,0 +1,103 @@ +package com.coding.week5.stack; + +import com.coding.weak1.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 stack = new Stack(); + Stack stack1 = new Stack(); + while (!s.isEmpty()) { + stack.push(s.pop()); + } + while (!stack.isEmpty()) { + stack1.push(stack.pop()); + } + while (!stack1.isEmpty()) { + s.push(stack1.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + Stack stack = new Stack(); + while (!s.isEmpty()){ + Object o1 = s.pop(); + if (!o.equals(o1)) { + stack.push(o1); + } + } + while (!stack.isEmpty()) { + s.push(stack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len > s.size() || len <= 0) { + throw new IllegalArgumentException(len+""); + } + + Object[] objects = new Object[len]; + for (int i = 0; i < len; i++) { + objects[i] = s.pop(); + } + for (int i = len - 1; i >= 0 ; i--) { + s.push(objects[i]); + } + return objects; + } + /** + * 字符串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){ + Stack stack = new Stack(); + char[] chars = s.toCharArray(); + for (char c : chars) { + if (c == '(' || c == '{' || c == '[') { + stack.push(c); + } else if (c == ')' || c == '}' || c == ']'){ + if (stack.isEmpty()) { + return false; + } + if (!isPair((char)stack.pop(), c)){ + return false; + } + } + } + return stack.isEmpty(); + } + + private static boolean isPair(char left, char right) { + switch (left) { + case '{': + return right == '}'; + case '[': + return right == ']'; + case '(': + return right == ')'; + default: + return false; + } + } + +} diff --git a/group24/494800949/src/test/java/com/coding/mini_jvm/test/ClassFileloaderTest.java b/group24/494800949/src/test/java/com/coding/mini_jvm/test/ClassFileloaderTest.java index 830d0b7efe..a03f29c0c3 100644 --- a/group24/494800949/src/test/java/com/coding/mini_jvm/test/ClassFileloaderTest.java +++ b/group24/494800949/src/test/java/com/coding/mini_jvm/test/ClassFileloaderTest.java @@ -1,6 +1,10 @@ package com.coding.mini_jvm.test; +import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; +import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassIndex; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.*; import com.coding.mini_jvm.src.com.coderising.jvm.loader.ClassFileLoader; +import com.coding.mini_jvm.src.com.coderising.jvm.util.Util; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -16,9 +20,19 @@ public class ClassFileloaderTest { static String path1 = "H:\\sourceCode\\coding2017\\group24\\494800949\\build\\classes\\test"; static String path2 = "C:\temp"; - - - + + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coding.mini_jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); +// clzFile.print(); + } + @Before public void setUp() throws Exception { } @@ -65,28 +79,95 @@ public void testMagicNumber(){ byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; - String acctualValue = this.byteToHexString(codes); + String acctualValue = Util.byteToHexString(codes); Assert.assertEquals("cafebabe", acctualValue); } - - - - - - - private 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()); } - return buffer.toString(); } + @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/group24/494800949/src/test/java/com/coding/week5/stack/StackUtilTest.java b/group24/494800949/src/test/java/com/coding/week5/stack/StackUtilTest.java new file mode 100644 index 0000000000..8e14b7cf00 --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week5/stack/StackUtilTest.java @@ -0,0 +1,56 @@ +package com.coding.week5.stack; + +import com.coding.weak1.Stack; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by Administrator on 2017/4/9 0009. + */ +public class StackUtilTest { + + private Stack stack; + + @Before + public void setup() { + stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + + } + @Test + public void reverse() throws Exception { + Assert.assertEquals("4,3,2,1",stack.toString()); + StackUtil.reverse(stack); + Assert.assertEquals("1,2,3,4",stack.toString()); + } + + @Test + public void remove() throws Exception { + StackUtil.remove(stack, 3); + Assert.assertEquals(stack.toString(), "4,2,1"); + } + + @Test + public void getTop() throws Exception { + Object[] objects = StackUtil.getTop(stack, 2); + Assert.assertEquals(objects[0], 4); + Assert.assertEquals(objects[1], 3); + } + + @Test + public void isValidPairs() throws Exception { + String str = "[abdd]}"; + Assert.assertEquals(StackUtil.isValidPairs(str), false); + str = "{add{ad[ddd]}}"; + Assert.assertEquals(StackUtil.isValidPairs(str), true); + str = "{add{ad[d(dd]}}"; + Assert.assertEquals(StackUtil.isValidPairs(str), false); + str = "{add{ad[d(d)d]}dfd}"; + Assert.assertEquals(StackUtil.isValidPairs(str), true); + } + +} \ No newline at end of file diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java new file mode 100644 index 0000000000..1e43329fcc --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java @@ -0,0 +1,132 @@ +package com.github.wdn.coding2017.basic.stack; + +import com.github.wdn.coding2017.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 stack = new Stack(); + Stack stack1 = new Stack(); + while (!s.isEmpty()){ + stack.push(s.pop()); + } + while (!stack.isEmpty()){ + stack1.push(stack.pop()); + } + while (!stack1.isEmpty()){ + s.push(stack1.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + Stack stack = new Stack(); + while (!s.isEmpty()) { + Object popObject = s.pop(); + if(popObject.equals(o)){ + break; + } + stack.push(popObject); + } + while (!stack.isEmpty()){ + s.push(stack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len > s.size() || len < 0) { + throw new IndexOutOfBoundsException(); + } + Object[] result = new Object[len]; + Stack stack = new Stack(); + for (int i = 0; i < len; i++) { + Object o = s.pop(); + result[i]=o; + stack.push(o); + } + while (!stack.isEmpty()){ + s.push(stack.pop()); + } + return result; + } + /** + * 字符串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.length()<2){ + return false; + } + Stack s1 = new Stack(); + Stack s2 = new Stack(); + char[] chars = s.toCharArray(); + int charsLength = chars.length; + if(charsLength%2==1 && isBrackets(chars[charsLength / 2])){ + return false; + } + for (int i = 0; i < charsLength/2; i++) { + char c = chars[i]; + if (isBrackets(c)) { + s1.push(c); + } + } + for (int i = charsLength-1; i > charsLength/2; i--) { + char c = chars[i]; + if (isBrackets(c)) { + s2.push(c); + } + } + if (s1.size() != s2.size()) { + return false; + } + for (int i = 0; i < s1.size(); i++) { + if (!isPairing((Character) s1.pop(), (Character) s2.pop())) { + return false; + } + } + return true; + } + // parenthesis 圆括号 + // square brackets 方括号 + // braces 大括号 + // 这里用bracket表示统称 + private static boolean isBrackets(char c){ + if('['==c||']'==c|| + '('==c||')'==c|| + '{'==c||'}'==c){ + return true; + } + return false; + } + + private static boolean isPairing(char left, char right) { + if(left=='(' && right==')'){ + return true; + }else if(left=='[' && right==']'){ + return true; + }else if(left=='{' && right=='}'){ + return true; + }else { + return false; + } + } +} diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..3a8f013b78 --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java @@ -0,0 +1,90 @@ +package com.github.wdn.coding2017.basic.stack.expr; + +import com.github.wdn.coding2017.basic.Stack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Administrator on 2017/4/13 0013. + */ +public class InfixExpr { + private String expr; + private static Map priorityMap = new HashMap(); + static{ + priorityMap.put("+",1); + priorityMap.put("-",1); + priorityMap.put("*",2); + priorityMap.put("/",2); + } + public InfixExpr(String expr) { + this.expr = expr; + } + public float calculate(float a,float b,String operator) throws IllegalAccessException { + float result; + switch (operator) { + case "+": + result = a+b; + break; + case "-": + result = a-b; + break; + case "*": + result = a*b; + break; + case "/": + result = a/b; + break; + default: + throw new IllegalAccessException(); + } + return result; + } + public float evaluate() { + try { + String[] numArr = expr.split("[+|\\-|*|/]"); + String[] operatorArr = expr.split("\\d+\\d*"); + Object[] operators = Arrays.stream(operatorArr).filter(x -> !"".equals(x.trim())).toArray(); + Stack numStack = new Stack(); + Stack operatorStack = new Stack(); + numStack.push(numArr[0]); + for (int i = 0; i < operators.length; i++) { + int number = Integer.parseInt(numArr[i + 1]); + String operator = operators[i].toString(); + if (!operatorStack.isEmpty() && priorityMap.get(operatorStack.peek()) < priorityMap.get(operator)) { + float currentResult = calculate(Integer.parseInt(numStack.pop().toString()), number, operator); + numStack.push(currentResult); + } else if(!operatorStack.isEmpty() && priorityMap.get(operatorStack.peek()) >= priorityMap.get(operator)){ + float b = Float.parseFloat(numStack.pop().toString()); + float a = Float.parseFloat(numStack.pop().toString()); + String currentOperator = operatorStack.pop().toString(); + float result = calculate(a, b, currentOperator); + numStack.push(result); + numStack.push(number); + operatorStack.push(operator); + }else { + numStack.push(number); + operatorStack.push(operator); + } + } + while (!operatorStack.isEmpty()) { + float b = Float.parseFloat(numStack.pop().toString()); + float a = Float.parseFloat(numStack.pop().toString()); + String operator = operatorStack.pop().toString(); + float result = calculate(a, b, operator); + numStack.push(result); + } + return Float.parseFloat(numStack.pop().toString()); + } catch (Exception e) { + e.printStackTrace(); + } + return 0; + } + + public static void main(String[] args) { + InfixExpr infixExpr = new InfixExpr("2+3*4+5"); + float r = infixExpr.evaluate(); + System.out.println(r); + } +} diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..a05f9fd578 --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,50 @@ +package com.github.wdn.coding2017.basic.stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by Administrator on 2017/4/13 0013. + */ +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java b/group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java new file mode 100644 index 0000000000..7e56bbf345 --- /dev/null +++ b/group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java @@ -0,0 +1,57 @@ +package com.github.wdn.coding2017.basic; + +import com.github.wdn.coding2017.basic.stack.StackUtil; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class StackUtilTest { + + @Test + public void testReverse(){ + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + StackUtil.reverse(stack); + while (!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } + @Test + public void testRemove(){ + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + StackUtil.remove(stack,4); + while (!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } + @Test + public void testGetTop(){ + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + Object[] o = StackUtil.getTop(stack,0); + System.out.println(Arrays.toString(o)); + while (!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } + @Test + public void testIsValidPairs(){ + Assert.assertEquals(true,StackUtil.isValidPairs("([e{d}f])")); + Assert.assertEquals(false,StackUtil.isValidPairs("([b{x]y})")); + Assert.assertEquals(false,StackUtil.isValidPairs("([({e}f])")); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..8ec8464918 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java @@ -0,0 +1,20 @@ +package com.github.wdn.coding2017.jvm.attr; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + + private int attributeNameIndex;// u2 + private int attributeLength; //u4 + public AttributeInfo(int attributeNameIndex,int attributeLength){ + this.attributeNameIndex = attributeNameIndex; + this.attributeLength = attributeLength; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..9400b629b2 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java @@ -0,0 +1,58 @@ +package com.github.wdn.coding2017.jvm.attr; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class CodeAttr extends AttributeInfo { + private int maxStack; + private int maxLocals; + private String code; + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + public CodeAttr(int attributeNameIndex, int attributeLength, int maxStack, int maxLocals, String code) { + super(attributeNameIndex, attributeLength); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.code = code; + } + @Override + public String toString(){ + return code; + } + public int getMaxStack() { + return maxStack; + } + + public void setMaxStack(int maxStack) { + this.maxStack = maxStack; + } + + public int getMaxLocals() { + return maxLocals; + } + + public void setMaxLocals(int maxLocals) { + this.maxLocals = maxLocals; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public void setLineNumTable(LineNumberTable lineNumTable) { + this.lineNumTable = lineNumTable; + } + + public void setLocalVarTable(LocalVariableTable localVarTable) { + this.localVarTable = localVarTable; + } + + public void setStackMapTable(StackMapTable stackMapTable) { + this.stackMapTable = stackMapTable; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..594e574114 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java @@ -0,0 +1,48 @@ +package com.github.wdn.coding2017.jvm.attr; + +import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class LineNumberTable extends AttributeInfo{ + public LineNumberTable(int attributeNameIndex, int attributeLength) { + super(attributeNameIndex, attributeLength); + } + List lineNumberItems = new ArrayList<>(); + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.lineNumberItems.add(item); + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + LineNumberTable lineNumberTable = new LineNumberTable(0, iter.readU4ToInt()); + int lineNumberTableCount = iter.readU2ToInt(); + for (int l = 0; l < lineNumberTableCount; l++) { + LineNumberItem lineNumberItem = new LineNumberItem(); + lineNumberItem.setStartPC(iter.readU2ToInt()); + lineNumberItem.setLineNum(iter.readU2ToInt()); + lineNumberTable.addLineNumberItem(lineNumberItem); + } + return lineNumberTable; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..f84a96e2d9 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java @@ -0,0 +1,80 @@ +package com.github.wdn.coding2017.jvm.attr; + +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class LocalVariableTable extends AttributeInfo{ + List localVariableTableItems = new ArrayList<>(); + public LocalVariableTable(int attributeNameIndex, int attributeLength) { + super(attributeNameIndex, attributeLength); + } + private static class LocalVariableTableItem{ + int startPC; + int length; + int nameIndex; + int descriptorIndex; + int index; + + public int getStartPC() { + return startPC; + } + + public void setStartPC(int startPC) { + this.startPC = startPC; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + } + private void addLocalVariableItem(LocalVariableTableItem item){ + this.localVariableTableItems.add(item); + } + public static LocalVariableTable parse(ByteCodeIterator iter) { + LocalVariableTable localVariableTable = new LocalVariableTable(iter.readU2ToInt(),iter.readU2ToInt()); + int LocalVariableTableCount = iter.readU2ToInt(); + for (int l = 0; l < LocalVariableTableCount; l++) { + LocalVariableTableItem item = new LocalVariableTableItem(); + item.setStartPC(iter.readU2ToInt()); + item.setLength(iter.readU2ToInt()); + item.setNameIndex(iter.readU2ToInt()); + item.setDescriptorIndex(iter.readU2ToInt()); + item.setIndex(iter.readU2ToInt()); + localVariableTable.addLocalVariableItem(item); + } + return localVariableTable; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java new file mode 100644 index 0000000000..cb05a8074d --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java @@ -0,0 +1,7 @@ +package com.github.wdn.coding2017.jvm.attr; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class LocalVariableTypeTable { +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..7c607031be --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java @@ -0,0 +1,29 @@ +package com.github.wdn.coding2017.jvm.attr; + +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class StackMapTable extends AttributeInfo{ + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.readU2ToInt(); + int len = iter.readU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.readCustomToString(len); + t.setOriginalCode(code); + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..a0fcba07f6 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java @@ -0,0 +1,37 @@ +package com.github.wdn.coding2017.jvm.clz; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class AccessFlag { + /* + enum { + ACC_PUBLIC,ACC_FINAL,ACC_SUPER,ACC_INTERFACE,ACC_ABSTRACT,ACC_SYNTHETIC + } + private int ACC_PUBLIC =0x0001; //可以被包的类外访问。 + private int ACC_FINAL =0x0010; //不允许有子类。 + private int ACC_SUPER =0x0020;//当用到invokespecial指令时,需要特殊处理③的父类方法。 + private int ACC_INTERFACE= 0x0200; //标识定义的是接口而不是类。 + private int ACC_ABSTRACT= 0x0400; //不能被实例化。 + private int ACC_SYNTHETIC= 0x1000; //标识并非Java源码生成的代码 + */ + 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; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..813c050a53 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java @@ -0,0 +1,80 @@ +package com.github.wdn.coding2017.jvm.clz; + +import com.github.wdn.coding2017.jvm.constant.ConstantPool; + +import java.util.List; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ClassFile { + private int minorVersion; + private int majorVersion; + private ConstantPool constantPool; + private AccessFlag accessFlag; + private ClassIndex classIndex; + private List fields; + private List methods; + public void print() { + } + + public int getMinorVersion() { + return minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public void setConstantPool(ConstantPool constantPool) { + this.constantPool = constantPool; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ClassIndex getClassIndex() { + return classIndex; + } + + public void setClassIndex(ClassIndex classIndex) { + this.classIndex = classIndex; + } + + public ClassIndex getClzIndex() { + return null; + } + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..f65a403d0a --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java @@ -0,0 +1,20 @@ +package com.github.wdn.coding2017.jvm.clz; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ClassIndex { + private int thisClassIndex; + private int superClassIndex; + public ClassIndex(int thisClassIndex,int superClassIndex){ + this.thisClassIndex = thisClassIndex; + this.superClassIndex = superClassIndex; + } + public int getThisClassIndex() { + return thisClassIndex; + } + + public int getSuperClassIndex() { + return superClassIndex; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java new file mode 100644 index 0000000000..8d557b10de --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java @@ -0,0 +1,74 @@ +package com.github.wdn.coding2017.jvm.clz; + +import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/4/10 0010. + */ +public class Field { + private AccessFlag accessFlag; // 例如是public , private 等等 + private int nameIndex; // 指向常量池的入口 + private int descriptorIndex; //指向常量池的入口 + private int attributesCount; // 该字段的属性有多少个 + private ConstantPool pool; + // attribute_info attributes[attributes_count]; //属性信息 + private Field(){ + } + public Field(ConstantPool pool){ + this.pool = pool; + } + public static Field parse(ByteCodeIterator iter){ + Field field = new Field(); + field.setAccessFlags(new AccessFlag(iter.readU2ToInt())); + field.setNameIndex(iter.readU2ToInt()); + field.setDescriptorIndex(iter.readU2ToInt()); + int attCount = iter.readU2ToInt(); + if(attCount>0){ + throw new RuntimeException("字段属性数量大于0"); + } + field.setAttributesCount(attCount); + return field; + } + public String toString(){ + return pool.getConstantInfo(nameIndex).getValue()+pool.getConstantInfo(descriptorIndex).getValue(); + } + public AccessFlag getAccessFlags() { + return accessFlag; + } + + public void setAccessFlags(AccessFlag accessFlags) { + this.accessFlag = accessFlags; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public int getAttributesCount() { + return attributesCount; + } + + public void setAttributesCount(int attributesCount) { + this.attributesCount = attributesCount; + } + + public void setPool(ConstantPool pool) { + this.pool = pool; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java new file mode 100644 index 0000000000..b6ace8ebce --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java @@ -0,0 +1,99 @@ +package com.github.wdn.coding2017.jvm.clz; + +import com.github.wdn.coding2017.jvm.attr.*; +import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +/** + * Created by Administrator on 2017/4/10 0010. + */ +public class Method { + private AccessFlag accessFlags; + private int nameIndex; + private int descriptorIndex; + private CodeAttr code; + //attributes[attributes_count]; + private ConstantPool pool; + public static Method parse(ConstantPool pool, ByteCodeIterator iter) { + Method method = new Method(); + method.setAccessFlags(new AccessFlag(iter.readU2ToInt())); + method.setNameIndex(iter.readU2ToInt()); + method.setDescriptorIndex(iter.readU2ToInt()); + int methodAttributesCount = iter.readU2ToInt(); + for (int j = 0; j < methodAttributesCount; j++) { + int methodAttributeNameIndex = iter.readU2ToInt(); + String methodAttributeType = pool.getConstantInfo(methodAttributeNameIndex).getValue(); + if (methodAttributeType.equals(AttributeInfo.CODE)) { + CodeAttr codeAttr = new CodeAttr(methodAttributeNameIndex, iter.readU4ToInt(), iter.readU2ToInt(), iter.readU2ToInt(), iter.readCustomToString(iter.readU4ToInt())); + int ExceptionCount = iter.readU2ToInt(); + if (ExceptionCount > 0) { + throw new RuntimeException("方法有异常待解析"); + } + int codeAttributesCount = iter.readU2ToInt(); + for (int k = 0; k < codeAttributesCount; k++) { + int codeAttributeNameIndex = iter.readU2ToInt(); + String codeAttributeType = pool.getConstantInfo(codeAttributeNameIndex).getValue(); + if ("LineNumberTable".equals(codeAttributeType)) { + LineNumberTable lineNumberTable = LineNumberTable.parse(iter); + codeAttr.setLineNumTable(lineNumberTable); + } else if ("LocalVariableTable".equals(codeAttributeType)) { + LocalVariableTable localVariableTable = LocalVariableTable.parse(iter); + codeAttr.setLocalVarTable(localVariableTable); + }else if ("StackMapTable".equals(codeAttributeType)) { + StackMapTable stackMapTable = StackMapTable.parse(iter); + codeAttr.setStackMapTable(stackMapTable); + } else { + throw new RuntimeException("未知的Code附加属性类型" + codeAttributeType); + } + } + method.setCode(codeAttr); + } else { + throw new RuntimeException("未知的方法属性类型" + methodAttributeType); + } + } + return method; + } + @Override + public String toString(){ + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append(pool.getConstantInfo(nameIndex).getValue()); + stringBuffer.append(pool.getConstantInfo(descriptorIndex).getValue()); + stringBuffer.append(code); + return stringBuffer.toString(); + } + public AccessFlag getAccessFlags() { + return accessFlags; + } + + public void setAccessFlags(AccessFlag accessFlags) { + this.accessFlags = accessFlags; + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public CodeAttr getCode() { + return code; + } + + public void setCode(CodeAttr code) { + this.code = code; + } + + public void setPool(ConstantPool pool) { + this.pool = pool; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..e4565e93b1 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java @@ -0,0 +1,35 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ClassInfo extends ConstantInfo{ + private int nameIndex; + public ClassInfo(ConstantPool constantPool){ + super(constantPool); + } + @Override + public int getType() { + return CLASS_INFO; + } + @Override + public String getValue() { + return getConstantPool().getConstantInfo(nameIndex).getValue(); + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getUtf8Index() { + return nameIndex; + } + + public String getClassName() { + return getConstantPool().getConstantInfo(nameIndex).getValue(); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..24975d30c8 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java @@ -0,0 +1,30 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +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 constantPool){ + this.constantPool = constantPool; + } + public abstract int getType(); + public abstract String getValue(); + public ConstantPool getConstantPool(){ + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return constantPool.getConstantInfo(index); + } + +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..3a3f4e03e4 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package com.github.wdn.coding2017.jvm.constant; + + +import java.util.ArrayList; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ConstantPool { + public static ArrayList constantPool = new ArrayList(); + static{ + constantPool.add(new NullConstantInfo()); + } + public void put(ConstantInfo info){ + constantPool.add(info); + } + public int getSize() { + return constantPool.size()-1; + } + + public ConstantInfo getConstantInfo(int i) { + return constantPool.get(i); + } + @Override + public String toString(){ + StringBuffer stringBuffer = new StringBuffer(); + for (int i = 1; i < constantPool.size(); i++) { + stringBuffer.append("#"+i+"=>"+constantPool.get(i).getValue()); + } + return stringBuffer.toString(); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..86c89dc9c3 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java @@ -0,0 +1,39 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class FieldRefInfo extends ConstantInfo { + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool constantPool) { + super(constantPool); + } + + @Override + public int getType() { + return FIELD_INFO; + } + + @Override + public String getValue() { + return getConstantPool().getConstantInfo(classInfoIndex).getValue()+getConstantPool().getConstantInfo(nameAndTypeIndex).getValue(); + } + + 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; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..e4d6412cd1 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java @@ -0,0 +1,37 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class MethodRefInfo extends ConstantInfo { + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool constantPool) { + super(constantPool); + } + @Override + public int getType() { + return METHOD_INFO; + } + @Override + public String getValue() { + return getConstantPool().getConstantInfo(classInfoIndex).getValue()+getConstantPool().getConstantInfo(nameAndTypeIndex).getValue(); + } + + 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; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..3a3f1bf4c8 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,38 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class NameAndTypeInfo extends ConstantInfo{ + private int nameIndex; + private int descriptorIndex; + + public NameAndTypeInfo(ConstantPool constantPool) { + super(constantPool); + } + + @Override + public int getType() { + return 0; + } + @Override + public String getValue() { + return getConstantPool().getConstantInfo(nameIndex).getValue()+getConstantPool().getConstantInfo(descriptorIndex).getValue(); + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..bea4eb973f --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class NullConstantInfo extends ConstantInfo { + public int getType() { + return 0; + } + + public String getValue() { + return null; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..a4cbd7bb5d --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java @@ -0,0 +1,30 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class StringInfo extends ConstantInfo { + public StringInfo(ConstantPool constantPool) { + super(constantPool); + } + + private int stringIndex; + + @Override + public int getType() { + return 0; + } + + @Override + public String getValue() { + return getConstantPool().getConstantInfo(stringIndex).getValue(); + } + + public int getStringIndex() { + return stringIndex; + } + + public void setStringIndex(int stringIndex) { + this.stringIndex = stringIndex; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..bf5efd842a --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java @@ -0,0 +1,23 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class UTF8Info extends ConstantInfo{ + private String value; + public UTF8Info(ConstantPool constantPool){ + super(constantPool); + } + @Override + public int getType() { + return UTF8_INFO; + } + @Override + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..dc4c1c0b54 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,42 @@ +package com.github.wdn.coding2017.jvm.loader; + + +import com.github.wdn.coding2017.jvm.util.Util; + +import java.nio.charset.Charset; + +public class ByteCodeIterator { + private byte[] bytes; + private int index; + + public ByteCodeIterator(byte[] bytes){ + this.bytes = bytes; + } + + public byte[] read(){ + return new byte[]{bytes[index++]}; + } + public int readToInt(){ + return Util.byteToInt(new byte[]{bytes[index++]}); + } + public int readU2ToInt(){ + return Util.byteToInt(new byte[]{bytes[index++],bytes[index++]}); + } + public String readU2ToString(){ + return Util.byteToHexString(new byte[]{bytes[index++],bytes[index++]}); + } + public int readU4ToInt(){ + return Util.byteToInt(new byte[]{bytes[index++],bytes[index++],bytes[index++],bytes[index++]}); + } + public String readU4ToString(){ + return Util.byteToHexString(new byte[]{bytes[index++],bytes[index++],bytes[index++],bytes[index++]}); + } + public String readCustomToString(int len){ + byte[] b = new byte[len]; + for (int i = 0; i < len; i++) { + b[i] = bytes[index++]; + } + return new String(b); + //return Util.byteToHexString(b); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java index 20c8183f3a..6f29b692d4 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java @@ -1,5 +1,6 @@ package com.github.wdn.coding2017.jvm.loader; +import com.github.wdn.coding2017.jvm.clz.ClassFile; import org.apache.commons.io.FileUtils; import java.io.File; @@ -38,7 +39,7 @@ public byte[] readBinaryCode(String className) { int offset=0; // for循环使用inputStream api读取 一次读完。。 for(offset = 0; offset < fileLength && (len = inputStream.read(fileBytes, offset, (int)fileLength - offset)) != -1; offset += len) { - System.out.println("dd"); + ; } // while循环使用System.arraycopy读取 /*while ((len = inputStream.read(bytes))>-1){ @@ -73,8 +74,10 @@ public String getClassPath(){ return stringBuffer.toString(); } - - - + public ClassFile loadClass(String className) { + ClassFileParser classFileParser = new ClassFileParser(); + ClassFile classFile = classFileParser.parse(readBinaryCode(className)); + return classFile; + } } diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..22d2e5bcd7 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java @@ -0,0 +1,105 @@ +package com.github.wdn.coding2017.jvm.loader; + +import com.github.wdn.coding2017.jvm.clz.*; +import com.github.wdn.coding2017.jvm.constant.*; + +import java.util.ArrayList; +import java.util.List; + +public class ClassFileParser { + ConstantPool pool = new ConstantPool(); + public ClassFile parse(byte[] codes) { + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magic = iter.readU4ToString(); + if(!"cafebabe".equals(magic)){ + throw new Error(); + } + ClassFile classFile = new ClassFile(); + classFile.setMinorVersion(iter.readU2ToInt()); + classFile.setMajorVersion(iter.readU2ToInt()); + classFile.setConstantPool(parseConstantPool(iter)); + classFile.setAccessFlag(parseAccessFlag(iter)); + classFile.setClassIndex(parseClassIndex(iter)); + parseInterface(iter); + classFile.setFields(parseField(iter)); + classFile.setMethods(parseMethod(iter)); + return classFile; + } + + private List parseMethod(ByteCodeIterator iter) { + int methodCount = iter.readU2ToInt(); + List methods = new ArrayList<>(methodCount); + for (int i = 0; i < methodCount; i++) { + Method method = Method.parse(pool, iter); + method.setPool(pool); + methods.add(method); + } + return methods; + } + + private List parseField(ByteCodeIterator iter) { + int fieldsCount = iter.readU2ToInt(); + List fields = new ArrayList<>(fieldsCount); + for (int i = 0; i < fieldsCount; i++) { + Field field = Field.parse(iter); + field.setPool(pool); + fields.add(field); + } + return fields; + } + + private void parseInterface(ByteCodeIterator iter){ + int interfaceNum = iter.readU2ToInt(); + if (interfaceNum > 0) { + throw new RuntimeException("接口数量>0"); + } + } + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + return new AccessFlag(iter.readU2ToInt()); + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + return new ClassIndex(iter.readU2ToInt(),iter.readU2ToInt()); + } + + public ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constantPoolNum = iter.readU2ToInt(); + for (int i = 0; i < constantPoolNum-1; i++) { + int type = iter.readToInt(); + if(type==7){// class + ClassInfo classInfo = new ClassInfo(pool); + classInfo.setNameIndex(iter.readU2ToInt()); + pool.put(classInfo); + }else if(type==9){// Fieldref + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(iter.readU2ToInt()); + fieldRefInfo.setNameAndTypeIndex(iter.readU2ToInt()); + pool.put(fieldRefInfo); + }else if(type==10){// Methodref + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(iter.readU2ToInt()); + methodRefInfo.setNameAndTypeIndex(iter.readU2ToInt()); + pool.put(methodRefInfo); + }else if(type==1){// Utf8 + int length = iter.readU2ToInt(); + String value = iter.readCustomToString(length); + UTF8Info utf8Info = new UTF8Info(pool); + utf8Info.setValue(value); + pool.put(utf8Info); + }else if(type==8){// String + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setStringIndex(iter.readU2ToInt()); + pool.put(stringInfo); + }else if(type==12){// NameAndType + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setNameIndex(iter.readU2ToInt()); + nameAndTypeInfo.setDescriptorIndex(iter.readU2ToInt()); + pool.put(nameAndTypeInfo); + }else{ + throw new RuntimeException("未知类型"+type); + } + } + return pool; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java index 346159abb5..9d2b468236 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java @@ -1,6 +1,10 @@ package com.github.wdn.coding2017.jvm.test; +import com.github.wdn.coding2017.jvm.clz.ClassFile; +import com.github.wdn.coding2017.jvm.clz.ClassIndex; +import com.github.wdn.coding2017.jvm.constant.*; import com.github.wdn.coding2017.jvm.loader.ClassFileLoader; +import com.github.wdn.coding2017.jvm.util.Util; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -16,8 +20,17 @@ public class ClassFileloaderTest { static String path1 = "E:\\softdata\\ideaworkspace\\self\\coding2017\\group24\\626451284\\mini-jvm\\target\\classes"; static String path2 = "E:\\temp"; - - + + static ClassFile clzFile = null; + static final String FULL_QUALIFIED_CLASS_NAME="com/coderising/jvm/test/EmployeeV1"; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.github.wdn.coding2017.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } @Before public void setUp() throws Exception { @@ -55,7 +68,6 @@ public void testClassFileLength() { } - @Test public void testMagicNumber(){ ClassFileLoader loader = new ClassFileLoader(); @@ -65,27 +77,93 @@ public void testMagicNumber(){ byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; - String acctualValue = this.byteToHexString(codes); + String acctualValue = Util.byteToHexString(codes); Assert.assertEquals("cafebabe", acctualValue); } - - - - - - - private 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.getNameIndex()); + Assert.assertEquals(14, nameAndType.getDescriptorIndex()); + } + //抽查几个吧 + { + 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()); } - return buffer.toString(); } + @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/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java new file mode 100644 index 0000000000..1e54f24a79 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.github.wdn.coding2017.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 - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group24/798277403/src/week1/ArrayList.java b/group24/798277403/src/basic/ArrayList.java similarity index 99% rename from group24/798277403/src/week1/ArrayList.java rename to group24/798277403/src/basic/ArrayList.java index 03257803df..436ca1f9f2 100644 --- a/group24/798277403/src/week1/ArrayList.java +++ b/group24/798277403/src/basic/ArrayList.java @@ -1,4 +1,4 @@ -package week1; +package basic; import java.util.Arrays; diff --git a/group24/798277403/src/week1/ArrayListTest.java b/group24/798277403/src/basic/ArrayListTest.java similarity index 98% rename from group24/798277403/src/week1/ArrayListTest.java rename to group24/798277403/src/basic/ArrayListTest.java index 98e30a222a..c50af7befa 100644 --- a/group24/798277403/src/week1/ArrayListTest.java +++ b/group24/798277403/src/basic/ArrayListTest.java @@ -1,4 +1,4 @@ -package week1; +package basic; import org.junit.Assert; import org.junit.Before; diff --git a/group24/798277403/src/week1/BinaryTree.java b/group24/798277403/src/basic/BinaryTree.java similarity index 99% rename from group24/798277403/src/week1/BinaryTree.java rename to group24/798277403/src/basic/BinaryTree.java index 3c480dc012..c2d5bb2c24 100644 --- a/group24/798277403/src/week1/BinaryTree.java +++ b/group24/798277403/src/basic/BinaryTree.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * Created by zhouliang on 2017-03-11. diff --git a/group24/798277403/src/week1/BinaryTreeNode.java b/group24/798277403/src/basic/BinaryTreeNode.java similarity index 99% rename from group24/798277403/src/week1/BinaryTreeNode.java rename to group24/798277403/src/basic/BinaryTreeNode.java index e680d5ed15..599b2b1ca8 100644 --- a/group24/798277403/src/week1/BinaryTreeNode.java +++ b/group24/798277403/src/basic/BinaryTreeNode.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * 自己实现的BinaryTreeNode diff --git a/group24/798277403/src/week1/Iterator.java b/group24/798277403/src/basic/Iterator.java similarity index 90% rename from group24/798277403/src/week1/Iterator.java rename to group24/798277403/src/basic/Iterator.java index 73ba87c125..4c0fedf988 100644 --- a/group24/798277403/src/week1/Iterator.java +++ b/group24/798277403/src/basic/Iterator.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * 自己实现的Iterator diff --git a/group24/798277403/src/week4/LRU/LRUPageFrame.java b/group24/798277403/src/basic/LRU/LRUPageFrame.java similarity index 99% rename from group24/798277403/src/week4/LRU/LRUPageFrame.java rename to group24/798277403/src/basic/LRU/LRUPageFrame.java index cbbb26fc7f..e69e051321 100644 --- a/group24/798277403/src/week4/LRU/LRUPageFrame.java +++ b/group24/798277403/src/basic/LRU/LRUPageFrame.java @@ -1,4 +1,4 @@ -package week4.LRU; +package basic.LRU; /** * Created by zhouliang on 2017-04-04. diff --git a/group24/798277403/src/week4/LRU/LRUPageFrameTest.java b/group24/798277403/src/basic/LRU/LRUPageFrameTest.java similarity index 98% rename from group24/798277403/src/week4/LRU/LRUPageFrameTest.java rename to group24/798277403/src/basic/LRU/LRUPageFrameTest.java index 0b6bdf2c25..4993f42e75 100644 --- a/group24/798277403/src/week4/LRU/LRUPageFrameTest.java +++ b/group24/798277403/src/basic/LRU/LRUPageFrameTest.java @@ -1,4 +1,4 @@ -package week4.LRU; +package basic.LRU; import org.junit.Assert; import org.junit.Test; diff --git a/group24/798277403/src/week4/LRU/MyLRUPageFrame.java b/group24/798277403/src/basic/LRU/MyLRUPageFrame.java similarity index 99% rename from group24/798277403/src/week4/LRU/MyLRUPageFrame.java rename to group24/798277403/src/basic/LRU/MyLRUPageFrame.java index 9e720d8589..b2387dbd81 100644 --- a/group24/798277403/src/week4/LRU/MyLRUPageFrame.java +++ b/group24/798277403/src/basic/LRU/MyLRUPageFrame.java @@ -1,4 +1,4 @@ -package week4.LRU; +package basic.LRU; /** * Created by zhouliang on 2017-04-04. diff --git a/group24/798277403/src/week1/LinkedList.java b/group24/798277403/src/basic/LinkedList.java similarity index 98% rename from group24/798277403/src/week1/LinkedList.java rename to group24/798277403/src/basic/LinkedList.java index e0160d0e5f..30d0b4a099 100644 --- a/group24/798277403/src/week1/LinkedList.java +++ b/group24/798277403/src/basic/LinkedList.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * 自己实现的LinkedList @@ -228,7 +228,7 @@ public void removeRange(int min, int max){ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ - public LinkedList intersection( LinkedList list){ + public LinkedList intersection(LinkedList list){ return null; } } diff --git a/group24/798277403/src/week1/LinkedListTest.java b/group24/798277403/src/basic/LinkedListTest.java similarity index 98% rename from group24/798277403/src/week1/LinkedListTest.java rename to group24/798277403/src/basic/LinkedListTest.java index 9a8a9d936d..0611a1ddb7 100644 --- a/group24/798277403/src/week1/LinkedListTest.java +++ b/group24/798277403/src/basic/LinkedListTest.java @@ -1,4 +1,4 @@ -package week1; +package basic; import org.junit.Before; import org.junit.Test; diff --git a/group24/798277403/src/week1/List.java b/group24/798277403/src/basic/List.java similarity index 93% rename from group24/798277403/src/week1/List.java rename to group24/798277403/src/basic/List.java index 982885508f..c46d81d175 100644 --- a/group24/798277403/src/week1/List.java +++ b/group24/798277403/src/basic/List.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * 自己定义的List接口 diff --git a/group24/798277403/src/week1/Queue.java b/group24/798277403/src/basic/Queue.java similarity index 97% rename from group24/798277403/src/week1/Queue.java rename to group24/798277403/src/basic/Queue.java index 184f3a5336..371f2f9340 100644 --- a/group24/798277403/src/week1/Queue.java +++ b/group24/798277403/src/basic/Queue.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * 自己实现的Queue,用自己的LinkedList实现 diff --git a/group24/798277403/src/week1/QueueTest.java b/group24/798277403/src/basic/QueueTest.java similarity index 97% rename from group24/798277403/src/week1/QueueTest.java rename to group24/798277403/src/basic/QueueTest.java index b5a333f64d..8af2de5ada 100644 --- a/group24/798277403/src/week1/QueueTest.java +++ b/group24/798277403/src/basic/QueueTest.java @@ -1,4 +1,4 @@ -package week1; +package basic; import org.junit.Before; import org.junit.Test; diff --git a/group24/798277403/src/week1/Stack.java b/group24/798277403/src/basic/Stack.java similarity index 97% rename from group24/798277403/src/week1/Stack.java rename to group24/798277403/src/basic/Stack.java index f85aa2ada5..e6351da277 100644 --- a/group24/798277403/src/week1/Stack.java +++ b/group24/798277403/src/basic/Stack.java @@ -1,4 +1,4 @@ -package week1; +package basic; /** * 自己实现的Stack diff --git a/group24/798277403/src/week1/StackTest.java b/group24/798277403/src/basic/StackTest.java similarity index 97% rename from group24/798277403/src/week1/StackTest.java rename to group24/798277403/src/basic/StackTest.java index f4213d66d3..921560a0f0 100644 --- a/group24/798277403/src/week1/StackTest.java +++ b/group24/798277403/src/basic/StackTest.java @@ -1,4 +1,4 @@ -package week1; +package basic; import org.junit.Before; import org.junit.Test; diff --git a/group24/798277403/src/week2/array/ArrayUtil.java b/group24/798277403/src/basic/array/ArrayUtil.java similarity index 99% rename from group24/798277403/src/week2/array/ArrayUtil.java rename to group24/798277403/src/basic/array/ArrayUtil.java index 04c03f95e0..e29a4845bf 100644 --- a/group24/798277403/src/week2/array/ArrayUtil.java +++ b/group24/798277403/src/basic/array/ArrayUtil.java @@ -1,4 +1,4 @@ -package week2.array; +package basic.array; import java.util.Arrays; diff --git a/group24/798277403/src/week2/array/ArrayUtilTest.java b/group24/798277403/src/basic/array/ArrayUtilTest.java similarity index 99% rename from group24/798277403/src/week2/array/ArrayUtilTest.java rename to group24/798277403/src/basic/array/ArrayUtilTest.java index 77c99242fa..792c778e75 100644 --- a/group24/798277403/src/week2/array/ArrayUtilTest.java +++ b/group24/798277403/src/basic/array/ArrayUtilTest.java @@ -1,4 +1,4 @@ -package week2.array; +package basic.array; import org.junit.Assert; import org.junit.Before; diff --git a/group24/798277403/src/week3/linkedlist/LinkedList.java b/group24/798277403/src/basic/linkedlist/LinkedList.java similarity index 99% rename from group24/798277403/src/week3/linkedlist/LinkedList.java rename to group24/798277403/src/basic/linkedlist/LinkedList.java index ad4560ad7d..53c9200412 100644 --- a/group24/798277403/src/week3/linkedlist/LinkedList.java +++ b/group24/798277403/src/basic/linkedlist/LinkedList.java @@ -1,4 +1,4 @@ -package week3.linkedlist; +package basic.linkedlist; /** diff --git a/group24/798277403/src/week3/linkedlist/LinkedListTest.java b/group24/798277403/src/basic/linkedlist/LinkedListTest.java similarity index 95% rename from group24/798277403/src/week3/linkedlist/LinkedListTest.java rename to group24/798277403/src/basic/linkedlist/LinkedListTest.java index fa648edfc6..4f74499501 100644 --- a/group24/798277403/src/week3/linkedlist/LinkedListTest.java +++ b/group24/798277403/src/basic/linkedlist/LinkedListTest.java @@ -1,4 +1,4 @@ -package week3.linkedlist; +package basic.linkedlist; import org.junit.Before; import org.junit.Test; @@ -8,7 +8,7 @@ */ public class LinkedListTest { - private week3.linkedlist.LinkedList myLinkedList = new week3.linkedlist.LinkedList<>(); + private LinkedList myLinkedList = new LinkedList<>(); private java.util.LinkedList systemLinkedList = new java.util.LinkedList<>(); diff --git a/group24/798277403/src/week3/linkedlist/List.java b/group24/798277403/src/basic/linkedlist/List.java similarity index 89% rename from group24/798277403/src/week3/linkedlist/List.java rename to group24/798277403/src/basic/linkedlist/List.java index a3245a5eb9..3b9dfb132a 100644 --- a/group24/798277403/src/week3/linkedlist/List.java +++ b/group24/798277403/src/basic/linkedlist/List.java @@ -1,4 +1,4 @@ -package week3.linkedlist; +package basic.linkedlist; /** * 自己定义的List接口 diff --git a/group24/798277403/src/basic/stack/StackUtil.java b/group24/798277403/src/basic/stack/StackUtil.java new file mode 100644 index 0000000000..7e5c157306 --- /dev/null +++ b/group24/798277403/src/basic/stack/StackUtil.java @@ -0,0 +1,116 @@ +package basic.stack; + +import java.util.Stack; + +/** + * Created by zhouliang on 2017-04-08. + */ +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.empty()){ + return; + } + int i = getAndRemoveBottom(s); // 依次返回1、2、3 + reverse(s); + s.push(i); + } + + //移除并返回当前的栈底元素 + private static int getAndRemoveBottom(Stack s){ + int result = s.pop(); + if(s.empty()){ + return result; + }else{ + int bottom = getAndRemoveBottom(s); + s.push(result); + return bottom; + } + } + + + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param o + */ + public static void remove(Stack s,Object o) { + if(s.empty()){ + return; + } + Object temp = s.pop(); + if(temp == o){ + return; + } + remove(s,o); + s.push(temp); + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + Object[] result = new Object[len]; + int index = 0; + while(index s, int index){ + Object temp = s.pop(); + index--; + if(0 == index){ + s.push(temp); + return temp; + } + Object result = getIndex(s,index); + s.push(temp); + return result; + } + + + /** + * 字符串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){ + char[] chars = s.toCharArray(); + Stack stack = new Stack(); + for(char c : chars){ + if(c=='(' || c=='[' || c=='{'){ + stack.push(c); + }else if(c==')'){ + char top = stack.peek(); + if(top == '('){ + stack.pop(); + } + }else if(c==']'){ + char top = stack.peek(); + if(top == '['){ + stack.pop(); + } + }else if(c=='}'){ + char top = stack.peek(); + if(top == '{'){ + stack.pop(); + } + } + } + + return stack.empty(); + } +} diff --git a/group24/798277403/src/basic/stack/StackUtilTest.java b/group24/798277403/src/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..c5ecd1fcbe --- /dev/null +++ b/group24/798277403/src/basic/stack/StackUtilTest.java @@ -0,0 +1,77 @@ +package basic.stack; + +import org.junit.Test; + +import java.util.Stack; + +/** + * Created by zhouliang on 2017-04-08. + */ +public class StackUtilTest { + + @Test + public void testReverse(){ + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + while(!s.isEmpty()){ + System.out.println(s.pop()); + } + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + StackUtil.reverse(s); + while(!s.isEmpty()){ + System.out.println(s.pop()); + } + } + + @Test + public void remove(){ + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + + StackUtil.remove(s,3); + while(!s.isEmpty()){ + System.out.println(s.pop()); + } + } + + @Test + public void getTop(){ + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + + Object[] result = StackUtil.getTop(s,2); + while(!s.isEmpty()){ + System.out.println(s.pop()); + } + + for(Object o : result){ + System.out.println(o); + } + } + + @Test + public void isValidPairs(){ + String s = "([e{d}f])"; + String s1 = "([b{x]y})"; + boolean result = StackUtil.isValidPairs(s); + System.out.println(result); + boolean result1 = StackUtil.isValidPairs(s1); + System.out.println(result1); + } +} diff --git a/group24/798277403/src/week3/DownloadThread.java b/group24/798277403/src/download/DownloadThread.java similarity index 83% rename from group24/798277403/src/week3/DownloadThread.java rename to group24/798277403/src/download/DownloadThread.java index 6361f6b394..df55a6fee1 100644 --- a/group24/798277403/src/week3/DownloadThread.java +++ b/group24/798277403/src/download/DownloadThread.java @@ -1,7 +1,7 @@ -package week3; +package download; -import week3.api.Connection; +import download.api.Connection; import java.io.RandomAccessFile; import java.util.concurrent.CyclicBarrier; @@ -13,7 +13,7 @@ class DownloadThread extends Thread{ private int endPos; private CyclicBarrier barrier; private String localFile; - public DownloadThread( 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; diff --git a/group24/798277403/src/week3/FileDownloader.java b/group24/798277403/src/download/FileDownloader.java similarity index 96% rename from group24/798277403/src/week3/FileDownloader.java rename to group24/798277403/src/download/FileDownloader.java index 912fc47df3..928c1cf2e5 100644 --- a/group24/798277403/src/week3/FileDownloader.java +++ b/group24/798277403/src/download/FileDownloader.java @@ -1,9 +1,9 @@ -package week3; +package download; -import week3.api.Connection; -import week3.api.ConnectionManager; -import week3.api.DownloadListener; +import download.api.Connection; +import download.api.ConnectionManager; +import download.api.DownloadListener; import java.io.IOException; import java.io.RandomAccessFile; diff --git a/group24/798277403/src/download/api/Connection.java b/group24/798277403/src/download/api/Connection.java new file mode 100644 index 0000000000..49ee91a647 --- /dev/null +++ b/group24/798277403/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/group24/798277403/src/week3/api/ConnectionException.java b/group24/798277403/src/download/api/ConnectionException.java similarity index 85% rename from group24/798277403/src/week3/api/ConnectionException.java rename to group24/798277403/src/download/api/ConnectionException.java index a92938a3aa..aa642f6adf 100644 --- a/group24/798277403/src/week3/api/ConnectionException.java +++ b/group24/798277403/src/download/api/ConnectionException.java @@ -1,4 +1,4 @@ -package week3.api; +package download.api; public class ConnectionException extends Exception { public ConnectionException(Exception e){ diff --git a/group24/798277403/src/download/api/ConnectionManager.java b/group24/798277403/src/download/api/ConnectionManager.java new file mode 100644 index 0000000000..de6df6d7c6 --- /dev/null +++ b/group24/798277403/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/group24/798277403/src/download/api/DownloadListener.java b/group24/798277403/src/download/api/DownloadListener.java new file mode 100644 index 0000000000..4119e46144 --- /dev/null +++ b/group24/798277403/src/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group24/798277403/src/week3/impl/ConnectionImpl.java b/group24/798277403/src/download/impl/ConnectionImpl.java similarity index 91% rename from group24/798277403/src/week3/impl/ConnectionImpl.java rename to group24/798277403/src/download/impl/ConnectionImpl.java index ca5c79c503..675d042a93 100644 --- a/group24/798277403/src/week3/impl/ConnectionImpl.java +++ b/group24/798277403/src/download/impl/ConnectionImpl.java @@ -1,7 +1,7 @@ -package week3.impl; +package download.impl; -import week3.api.Connection; -import week3.api.ConnectionException; +import download.api.Connection; +import download.api.ConnectionException; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -12,7 +12,7 @@ import java.net.URLConnection; import java.util.Arrays; -class ConnectionImpl implements Connection{ +class ConnectionImpl implements Connection { private URL url; diff --git a/group01/895457260/code/src/download/impl/ConnectionManagerImpl.java b/group24/798277403/src/download/impl/ConnectionManagerImpl.java similarity index 99% rename from group01/895457260/code/src/download/impl/ConnectionManagerImpl.java rename to group24/798277403/src/download/impl/ConnectionManagerImpl.java index be17fa9110..e721d46194 100644 --- a/group01/895457260/code/src/download/impl/ConnectionManagerImpl.java +++ b/group24/798277403/src/download/impl/ConnectionManagerImpl.java @@ -5,8 +5,10 @@ import download.api.ConnectionManager; public class ConnectionManagerImpl implements ConnectionManager { + @Override public Connection open(String url) throws ConnectionException { return new ConnectionImpl(url); } + } diff --git a/group24/798277403/src/week3/test/ConnectionTest.java b/group24/798277403/src/download/test/ConnectionTest.java similarity index 88% rename from group24/798277403/src/week3/test/ConnectionTest.java rename to group24/798277403/src/download/test/ConnectionTest.java index 918f4d0707..cd8c9ca04d 100644 --- a/group24/798277403/src/week3/test/ConnectionTest.java +++ b/group24/798277403/src/download/test/ConnectionTest.java @@ -1,12 +1,13 @@ -package week3.test; +package download.test; +import download.api.Connection; +import download.api.ConnectionManager; +import download.impl.ConnectionManagerImpl; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import week3.api.Connection; -import week3.api.ConnectionManager; -import week3.impl.ConnectionManagerImpl; + public class ConnectionTest { diff --git a/group24/798277403/src/week3/test/FileDownloaderTest.java b/group24/798277403/src/download/test/FileDownloaderTest.java similarity index 86% rename from group24/798277403/src/week3/test/FileDownloaderTest.java rename to group24/798277403/src/download/test/FileDownloaderTest.java index 959796399b..f0337f6bc1 100644 --- a/group24/798277403/src/week3/test/FileDownloaderTest.java +++ b/group24/798277403/src/download/test/FileDownloaderTest.java @@ -1,12 +1,13 @@ -package week3.test; +package download.test; +import download.FileDownloader; +import download.api.ConnectionManager; +import download.api.DownloadListener; +import download.impl.ConnectionManagerImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; -import week3.FileDownloader; -import week3.api.ConnectionManager; -import week3.api.DownloadListener; -import week3.impl.ConnectionManagerImpl; + public class FileDownloaderTest { diff --git a/group24/798277403/src/week2/litestruts/LoginAction.java b/group24/798277403/src/litestruts/LoginAction.java similarity index 97% rename from group24/798277403/src/week2/litestruts/LoginAction.java rename to group24/798277403/src/litestruts/LoginAction.java index f819fd3aa3..8c448e3630 100644 --- a/group24/798277403/src/week2/litestruts/LoginAction.java +++ b/group24/798277403/src/litestruts/LoginAction.java @@ -1,4 +1,4 @@ -package week2.litestruts; +package litestruts; /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 diff --git a/group24/798277403/src/week2/litestruts/Struts.java b/group24/798277403/src/litestruts/Struts.java similarity index 98% rename from group24/798277403/src/week2/litestruts/Struts.java rename to group24/798277403/src/litestruts/Struts.java index 4063dcda68..2139dd8551 100644 --- a/group24/798277403/src/week2/litestruts/Struts.java +++ b/group24/798277403/src/litestruts/Struts.java @@ -1,4 +1,4 @@ -package week2.litestruts; +package litestruts; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; @@ -44,7 +44,7 @@ public static View runAction(String actionName, Map parameters) View view = new View(); try { db = documentBuilderFactory.newDocumentBuilder(); - Document document = db.parse("src/week2/litestruts/struts.xml"); + Document document = db.parse("src/litestruts/struts.xml"); NodeList nodeList = document.getElementsByTagName("action"); //遍历每一个action节点 diff --git a/group24/798277403/src/litestruts/StrutsTest.java b/group24/798277403/src/litestruts/StrutsTest.java new file mode 100644 index 0000000000..868a78cdba --- /dev/null +++ b/group24/798277403/src/litestruts/StrutsTest.java @@ -0,0 +1,40 @@ +package litestruts; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + + +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/798277403/src/litestruts/View.java b/group24/798277403/src/litestruts/View.java new file mode 100644 index 0000000000..1eed614744 --- /dev/null +++ b/group24/798277403/src/litestruts/View.java @@ -0,0 +1,23 @@ +package 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/798277403/src/mini_jvm/clz/AccessFlag.java b/group24/798277403/src/mini_jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..b6717402da --- /dev/null +++ b/group24/798277403/src/mini_jvm/clz/AccessFlag.java @@ -0,0 +1,25 @@ +package mini_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/group24/798277403/src/mini_jvm/clz/ClassFile.java b/group24/798277403/src/mini_jvm/clz/ClassFile.java new file mode 100644 index 0000000000..4cf756c090 --- /dev/null +++ b/group24/798277403/src/mini_jvm/clz/ClassFile.java @@ -0,0 +1,65 @@ +package mini_jvm.clz; + + +import mini_jvm.constant.ClassInfo; +import mini_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/group24/798277403/src/mini_jvm/clz/ClassIndex.java b/group24/798277403/src/mini_jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..dcc59908f0 --- /dev/null +++ b/group24/798277403/src/mini_jvm/clz/ClassIndex.java @@ -0,0 +1,19 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/ClassInfo.java b/group24/798277403/src/mini_jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..ed39387440 --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/ClassInfo.java @@ -0,0 +1,24 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/ConstantInfo.java b/group24/798277403/src/mini_jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..d488321043 --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/ConstantInfo.java @@ -0,0 +1,29 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/ConstantPool.java b/group24/798277403/src/mini_jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..c8d30c78db --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/ConstantPool.java @@ -0,0 +1,27 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/FieldRefInfo.java b/group24/798277403/src/mini_jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..3d74c4244f --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/FieldRefInfo.java @@ -0,0 +1,54 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/MethodRefInfo.java b/group24/798277403/src/mini_jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..4037881ad8 --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/MethodRefInfo.java @@ -0,0 +1,55 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/NameAndTypeInfo.java b/group24/798277403/src/mini_jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..badba119df --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,45 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/NullConstantInfo.java b/group24/798277403/src/mini_jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..28d102c997 --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/NullConstantInfo.java @@ -0,0 +1,13 @@ +package mini_jvm.constant; + +public class NullConstantInfo extends ConstantInfo { + + public NullConstantInfo(){ + + } + @Override + public int getType() { + return -1; + } + +} diff --git a/group24/798277403/src/mini_jvm/constant/StringInfo.java b/group24/798277403/src/mini_jvm/constant/StringInfo.java new file mode 100644 index 0000000000..2a9387d247 --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/StringInfo.java @@ -0,0 +1,26 @@ +package mini_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/group24/798277403/src/mini_jvm/constant/UTF8Info.java b/group24/798277403/src/mini_jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..6fc44f5355 --- /dev/null +++ b/group24/798277403/src/mini_jvm/constant/UTF8Info.java @@ -0,0 +1,32 @@ +package mini_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/group24/798277403/src/mini_jvm/loader/ByteCodeIterator.java b/group24/798277403/src/mini_jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..35ca6420b6 --- /dev/null +++ b/group24/798277403/src/mini_jvm/loader/ByteCodeIterator.java @@ -0,0 +1,55 @@ +package mini_jvm.loader; + +import mini_jvm.util.Util; + +import java.util.Arrays; + +public class ByteCodeIterator { + private byte[] codes; + private int pos; + + public ByteCodeIterator(byte[] codes){ + this.codes = codes; + } + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1toInt() { + return Util.byteToInt(new byte[] { codes[pos++] }); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++] }); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }); + } + + public String nextU4ToHexString() { + return Util.byteToHexString((new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] })); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + + } + + public void back(int n) { + this.pos -= n; + } + +} diff --git a/group24/798277403/src/mini_jvm/loader/ClassFileLoader.java b/group24/798277403/src/mini_jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..db3402aeb6 --- /dev/null +++ b/group24/798277403/src/mini_jvm/loader/ClassFileLoader.java @@ -0,0 +1,94 @@ +package mini_jvm.loader; + +import mini_jvm.clz.ClassFile; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + 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 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/group24/798277403/src/mini_jvm/test/EmployeeV1.java b/group24/798277403/src/mini_jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..aed78de928 --- /dev/null +++ b/group24/798277403/src/mini_jvm/test/EmployeeV1.java @@ -0,0 +1,28 @@ +package mini_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/group24/798277403/src/mini_jvm/util/Util.java b/group24/798277403/src/mini_jvm/util/Util.java new file mode 100644 index 0000000000..bc2e724f03 --- /dev/null +++ b/group24/798277403/src/mini_jvm/util/Util.java @@ -0,0 +1,22 @@ +package mini_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 - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - /jsp/welcome.jsp - /jsp/error.jsp - - diff --git a/group24/798277403/src/week4/loader/ClassFileLoader.java b/group24/798277403/src/week4/loader/ClassFileLoader.java deleted file mode 100644 index 90bce86e77..0000000000 --- a/group24/798277403/src/week4/loader/ClassFileLoader.java +++ /dev/null @@ -1,67 +0,0 @@ -package week4.loader; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by zhouliang on 2017-04-04. - */ -public class ClassFileLoader { - private List clzPaths = new ArrayList(); - - public byte[] readBinaryCode(String className) { - className = className.replace(".","\\"); - if(!className.endsWith(".class")){ - className=className+".class"; - } - File file = null; - for(String path : clzPaths){ - file = new File(path+"\\"+className); - if(file.exists()){ - break; - } - } - - if(file==null){ - try { - throw new FileNotFoundException(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return null; - }else{ - byte[] buffer = new byte[1024]; - BufferedInputStream bufferedInputStream = null; - ByteArrayOutputStream byteArrayOutputStream = null; - try { - bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); - byteArrayOutputStream = new ByteArrayOutputStream(); - int length = 0; - while((length = bufferedInputStream.read(buffer))!= -1){ - byteArrayOutputStream.write(buffer,0,length); - } - } catch (IOException e) { - e.printStackTrace(); - } - return byteArrayOutputStream.toByteArray(); - } - } - - - public void addClassPath(String path) { - clzPaths.add(path); - } - - public String getClassPath(){ - StringBuilder stringBuilder = new StringBuilder(); - for(int i=0; i 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 list=new ArrayList(); int i=0; int j=0; diff --git a/group26/1515345281/src/week2/arrayutil/ArrayUtilTest.java b/group26/1515345281/src/week2/arrayutil/ArrayUtilTest.java index 7b0d3c94e0..f560b2d658 100644 --- a/group26/1515345281/src/week2/arrayutil/ArrayUtilTest.java +++ b/group26/1515345281/src/week2/arrayutil/ArrayUtilTest.java @@ -1,5 +1,5 @@ -package week2.test; +package week2.arrayutil; import static org.junit.Assert.*; diff --git a/group26/1515345281/src/week2/blog b/group26/1515345281/src/week2/blog new file mode 100644 index 0000000000..19c1272ec0 --- /dev/null +++ b/group26/1515345281/src/week2/blog @@ -0,0 +1 @@ +数筛法的具体应用--素数求解问题:http://blog.csdn.net/sjshenjian/article/details/68943399 \ No newline at end of file diff --git a/group26/1515345281/src/week2/struts2/Configuration.java b/group26/1515345281/src/week2/struts2/Configuration.java new file mode 100644 index 0000000000..ddb27cc229 --- /dev/null +++ b/group26/1515345281/src/week2/struts2/Configuration.java @@ -0,0 +1,122 @@ +package week2.struts2; + +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; + + +/** + * 配置解析struts.xml文件 + * @author Administrator + * + */ +public class Configuration { + + Map actions=new HashMap<>(); + + public Configuration(String fileName) { + + //获取当前类包名 + String packageName=this.getClass().getPackage().getName(); + + packageName=packageName.replace(".", "/"); + //获取文件流 + InputStream input=this.getClass().getResourceAsStream("/"+packageName+"/"+fileName); + + parseXml(input); + + try{ + input.close(); + }catch(IOException e){ + throw new ConfigurationException(e); + } + } + + private void parseXml(InputStream input) { + + SAXBuilder builder=new SAXBuilder(); + + try { + Document document=builder.build(input); + + Element root=document.getRootElement(); + + for(Element actionElement:root.getChildren("action")){ + + String actionName=actionElement.getAttributeValue("name"); + String clazzName=actionElement.getAttributeValue("class"); + + ActionConfig ac=new ActionConfig(actionName,clazzName); + + for(Element resultElement:actionElement.getChildren("result")){ + + String resultName=resultElement.getAttributeValue("name"); + String viewName=resultElement.getText().trim(); + + ac.setViewResult(resultName, viewName); + } + + actions.put(actionName, ac); + } + + } catch (JDOMException e) { + throw new ConfigurationException(e); + } catch (IOException e) { + throw new ConfigurationException(e); + } + + } + + public String getClassName(String actionName) { + + ActionConfig ac=this.actions.get(actionName); + + if(null == ac){ + return null; + } + + return ac.getClazzName(); + } + + public String getResultView(String actionName, String resultName) { + + ActionConfig ac=this.actions.get(actionName); + + if(null == ac){ + return null; + } + + return ac.getViewResult(resultName); + } + + private static class ActionConfig{ + + String actionName; + String clazzName; + Map viewResults=new HashMap<>(); + + public ActionConfig(String actionName,String clazzName){ + this.actionName=actionName; + this.clazzName=clazzName; + } + + public String getClazzName() { + return clazzName; + } + + public void setViewResult(String name,String viewName){ + viewResults.put(name, viewName); + } + + public String getViewResult(String name){ + String viewName=viewResults.get(name); + return viewName; + } + } +} diff --git a/group26/1515345281/src/week2/struts2/ConfigurationException.java b/group26/1515345281/src/week2/struts2/ConfigurationException.java new file mode 100644 index 0000000000..842ca1866b --- /dev/null +++ b/group26/1515345281/src/week2/struts2/ConfigurationException.java @@ -0,0 +1,20 @@ +package week2.struts2; + +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/group26/1515345281/src/week2/struts2/LoginAction.java b/group26/1515345281/src/week2/struts2/LoginAction.java index 0a34e92f18..7bfaee9134 100644 --- a/group26/1515345281/src/week2/struts2/LoginAction.java +++ b/group26/1515345281/src/week2/struts2/LoginAction.java @@ -1,39 +1,43 @@ package week2.struts2; -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @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; - } +public class LoginAction { + private String userName; + private String password; + private String message; + + + public String excute(){ + if("沈健".equals(userName) && "123456".equals(password)){ + this.message="login successful"; + return "success"; + } + + this.message="login failed,please check your user/pwd"; + return "fail"; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + } diff --git a/group26/1515345281/src/week2/struts2/ReflectionUtil.java b/group26/1515345281/src/week2/struts2/ReflectionUtil.java new file mode 100644 index 0000000000..0c9890019b --- /dev/null +++ b/group26/1515345281/src/week2/struts2/ReflectionUtil.java @@ -0,0 +1,88 @@ +package week2.struts2; + +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 { + + /** + * 反射赋值 + * @param o:类对象 + * @param params:用户信息 + */ + public static void setParameters(Object o, Map params){ + + List Methods=getSetterMethods(o.getClass()); + + for(String name:params.keySet()){ + + String methodName="set"+name; + + for(Method method:Methods){ + + if(method.getName().equalsIgnoreCase(methodName)){ + try { + method.invoke(o, params.get(name)); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } + + public static Map getParamterMap(Object o){ + + Map params=new HashMap<>(); + + List methods=getGetterMethods(o.getClass()); + + for(Method method:methods){ + + String name=method.getName().replaceFirst("get", "").toLowerCase(); + + try { + Object object=method.invoke(o); + params.put(name, object); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + e.printStackTrace(); + } + } + + return params; + } + + public static List getSetterMethods(Class clazz){ + return getMethod(clazz,"set"); + } + + public static List getGetterMethods(Class clazz){ + return getMethod(clazz,"get"); + } + + /** + *反射获取给定名开始的方法 + * @param clazz + * @param startWithName + * @return + */ + private static List getMethod(Class clazz, String startWithName) { + + List methods=new ArrayList(); + + for(Method method:clazz.getDeclaredMethods()){ + + if(method.getName().startsWith(startWithName)){ + methods.add(method); + } + } + + return methods; + } +} diff --git a/group26/1515345281/src/week2/struts2/Struts.java b/group26/1515345281/src/week2/struts2/Struts.java index 06edfe7e20..caca81418e 100644 --- a/group26/1515345281/src/week2/struts2/Struts.java +++ b/group26/1515345281/src/week2/struts2/Struts.java @@ -1,34 +1,63 @@ package week2.struts2; +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. 读取配置文件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; - } + private static final Configuration config = 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 clazzName= config.getClassName(actionName); + if (clazzName == null) { + return null; + } + + try { + + Class clazz=Class.forName(clazzName); + Object action=clazz.newInstance(); + + ReflectionUtil.setParameters(action,parameters); + + Method method=clazz.getDeclaredMethod("excute"); + String result=(String) method.invoke(action); + + Map params=new HashMap<>(); + params=ReflectionUtil.getParamterMap(action); + + String resultView=config.getResultView(actionName, result); + + View view=new View(); + view.setJsp(resultView); + view.setParameters(params); + + return view; + + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } } diff --git a/group26/1515345281/src/week2/struts2/StrutsTest.java b/group26/1515345281/src/week2/struts2/StrutsTest.java index 68ec3ee4b4..376f7fd431 100644 --- a/group26/1515345281/src/week2/struts2/StrutsTest.java +++ b/group26/1515345281/src/week2/struts2/StrutsTest.java @@ -1,5 +1,7 @@ package week2.struts2; +import static org.junit.Assert.*; + import java.util.HashMap; import java.util.Map; @@ -11,30 +13,27 @@ 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")); + String actionName="login"; + Map params=new HashMap<>(); + + params.put("userName", "沈健"); + params.put("password", "123456"); + + View view=Struts.runAction(actionName, params); + assertEquals("/jsp/homepage.jsp", view.getJsp()); + 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")); + String actionName="login"; + Map params=new HashMap<>(); + + params.put("name", "沈健"); + params.put("password", "1234565"); + + View view=Struts.runAction(actionName, params); + assertEquals("/jsp/showLogin.jsp", view.getJsp()); + assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); } } diff --git a/group26/1515345281/src/week2/struts2/View.java b/group26/1515345281/src/week2/struts2/View.java index 5a907a455f..7017ab58ab 100644 --- a/group26/1515345281/src/week2/struts2/View.java +++ b/group26/1515345281/src/week2/struts2/View.java @@ -13,6 +13,7 @@ public View setJsp(String jsp) { this.jsp = jsp; return this; } + public Map getParameters() { return parameters; } diff --git a/group26/1515345281/src/week2/struts2/struts.xml b/group26/1515345281/src/week2/struts2/struts.xml index 9e69fa4e47..f2fb0166e0 100644 --- a/group26/1515345281/src/week2/struts2/struts.xml +++ b/group26/1515345281/src/week2/struts2/struts.xml @@ -5,8 +5,9 @@ /jsp/showLogin.jsp - - /jsp/welcome.jsp + + /jsp/welcome.jsp /jsp/error.jsp + \ No newline at end of file diff --git a/group26/1515345281/src/week2/struts2/test/ConfigurationTest.java b/group26/1515345281/src/week2/struts2/test/ConfigurationTest.java new file mode 100644 index 0000000000..dbbaf30eee --- /dev/null +++ b/group26/1515345281/src/week2/struts2/test/ConfigurationTest.java @@ -0,0 +1,40 @@ +package week2.struts2.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import week2.struts2.Configuration; + +public class ConfigurationTest { + + Configuration config=new Configuration("struts.xml"); + + @Test + public void testGetClassName(){ + + String clazzName=config.getClassName("login"); + assertEquals("week2.struts2.LoginAction",clazzName); + + clazzName=config.getClassName("logout"); + assertEquals("week2.struts2.LoginOutAction",clazzName); + + clazzName=config.getClassName("logoutf"); + } + + @Test + public void testGetResultView(){ + + String jsp=config.getResultView("login","success"); + assertEquals("/jsp/homepage.jsp",jsp); + + jsp=config.getResultView("login", "fail"); + assertEquals("/jsp/showLogin.jsp",jsp); + + jsp=config.getResultView("logout", "success"); + assertEquals("/jsp/welcome.jsp",jsp); + + jsp=config.getResultView("logout", "error"); + assertEquals("/jsp/error.jsp",jsp); + } +} diff --git a/group26/1515345281/src/week2/struts2/test/ReflectionTest.java b/group26/1515345281/src/week2/struts2/test/ReflectionTest.java new file mode 100644 index 0000000000..44bebb2343 --- /dev/null +++ b/group26/1515345281/src/week2/struts2/test/ReflectionTest.java @@ -0,0 +1,110 @@ +package week2.struts2.test; + +import static org.junit.Assert.*; + +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.Before; +import org.junit.Test; + +import week2.struts2.LoginAction; +import week2.struts2.ReflectionUtil; + +public class ReflectionTest { + + @Test + public void testGetSetterMethods() throws ClassNotFoundException { + + String clazzName = "week2.struts2.LoginAction"; + + Class clazz = Class.forName(clazzName); + + List methods = ReflectionUtil.getSetterMethods(clazz); + + assertEquals(3, methods.size()); + + List expectedNames = new ArrayList(); + expectedNames.add("setUserName"); + expectedNames.add("setPassword"); + expectedNames.add("setMessage"); + + Set actualsNames = new HashSet<>(); + for (Method m : methods) { + actualsNames.add(m.getName()); + } + + assertTrue(actualsNames.containsAll(expectedNames)); + } + + @Test + public void testGetGetterMethods() throws ClassNotFoundException { + + String clazzName = "week2.struts2.LoginAction"; + Class clazz = Class.forName(clazzName); + List methods = ReflectionUtil.getGetterMethods(clazz); + + assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getUserName"); + expectedNames.add("getPassword"); + expectedNames.add("getMessage"); + + Set actualNames = new HashSet<>(); + for (Method m : methods) { + actualNames.add(m.getName()); + } + + assertTrue(actualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception { + + String clazzName = "week2.struts2.LoginAction"; + Class clazz = Class.forName(clazzName); + + Object o = clazz.newInstance(); + Map params = new HashMap<>(); + params.put("userName", "沈健"); + params.put("password", "123456"); + + ReflectionUtil.setParameters(o, params); + + Field userName = clazz.getDeclaredField("userName"); + userName.setAccessible(true); + assertEquals(userName.get(o), "沈健"); + + Field password = clazz.getDeclaredField("password"); + password.setAccessible(true); + assertEquals(password.get(o), "123456"); + + } + + @Test + public void testGetParameterMap() throws Exception { + + String clazzName = "week2.struts2.LoginAction"; + Class clazz = Class.forName(clazzName); + LoginAction action = (LoginAction) clazz.newInstance(); + action.setUserName("沈健"); + action.setPassword("123456"); + + Map params = ReflectionUtil.getParamterMap(action); + + Assert.assertEquals(3, params.size()); + + Assert.assertEquals(null, params.get("messaage")); + Assert.assertEquals("沈健", params.get("username")); + Assert.assertEquals("123456", params.get("password")); + } + +} diff --git a/group26/1515345281/src/week3/blog b/group26/1515345281/src/week3/blog new file mode 100644 index 0000000000..2c4d2cdc00 --- /dev/null +++ b/group26/1515345281/src/week3/blog @@ -0,0 +1 @@ +图片验证码生成 : http://blog.csdn.net/sjshenjian/article/details/68943294 \ No newline at end of file diff --git a/group26/1515345281/src/week3/download/DownloadThread.java b/group26/1515345281/src/week3/download/DownloadThread.java new file mode 100644 index 0000000000..21e29bac91 --- /dev/null +++ b/group26/1515345281/src/week3/download/DownloadThread.java @@ -0,0 +1,57 @@ +package week3.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import week3.download.api.Connection; + +public class DownloadThread extends Thread { + + Connection conn; + int startPos; + int endPos; + String localFile; + // 它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。 + // 在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待 + 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; + } + + @Override + 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) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + } +} diff --git a/group26/1515345281/src/week3/download/FileDownloader.java b/group26/1515345281/src/week3/download/FileDownloader.java new file mode 100644 index 0000000000..467c95843a --- /dev/null +++ b/group26/1515345281/src/week3/download/FileDownloader.java @@ -0,0 +1,106 @@ +package week3.download; + +import java.net.URL; +import java.util.concurrent.CyclicBarrier; + +import week3.download.api.Connection; +import week3.download.api.ConnectionException; +import week3.download.api.ConnectionManager; +import week3.download.api.DownloadListener; +import week3.download.api.impl.ConnectionManagerImpl; + +public class FileDownloader { + + private String url; + private String localFile; + private static final int DOWNLOAD_THREAD_NUM = 6; + + private DownloadListener listener; + + 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_THREAD_NUM, + new Runnable() { + @Override + public void run() { + listener.notifyFinished(); + } + }); + + ConnectionManager connManager = new ConnectionManagerImpl(); + + Connection conn = null; + + try { + conn = connManager.open(url); + int totalLen = conn.getContentLength(); + + int[][] range=allocateDownloadRange(DOWNLOAD_THREAD_NUM,totalLen); + + for (int i = 0; i < DOWNLOAD_THREAD_NUM; i++) { + + DownloadThread thread = new DownloadThread(connManager.open(url), range[i][0], + range[i][1], localFile, barrier); + + thread.start(); + } + + } catch (ConnectionException e) { + e.printStackTrace(); + } finally { + if (conn != null) { + conn.close(); + } + } + } + + private int[][] allocateDownloadRange(int threadNum,int totalLen){ + + int[][] range=new int[threadNum][2]; + + int eachThreadSize=totalLen/threadNum; + + int left=totalLen%threadNum;//剩余的由最后一个线程处理 + + for(int i=0;i totalLen){ + byte[] data=baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + +} diff --git a/group26/1515345281/src/week3/download/api/impl/ConnectionManagerImpl.java b/group26/1515345281/src/week3/download/api/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..47bfcc62d0 --- /dev/null +++ b/group26/1515345281/src/week3/download/api/impl/ConnectionManagerImpl.java @@ -0,0 +1,17 @@ +package week3.download.api.impl; + +import java.io.IOException; + +import week3.download.api.Connection; +import week3.download.api.ConnectionException; +import week3.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return new ConnectionImpl(url); + } + +} diff --git a/group26/1515345281/src/week3/download/test/ConnectionTest.java b/group26/1515345281/src/week3/download/test/ConnectionTest.java new file mode 100644 index 0000000000..36bb9d1761 --- /dev/null +++ b/group26/1515345281/src/week3/download/test/ConnectionTest.java @@ -0,0 +1,52 @@ +package week3.download.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import week3.download.api.Connection; +import week3.download.api.ConnectionManager; +import week3.download.api.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://pic.sc.chinaz.com/files/pic/pic9/201508/apic14052.jpg"); + Assert.assertEquals(112504, conn.getContentLength()); + } + + @Test + public void testRead() throws Exception{ + + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://pic.sc.chinaz.com/files/pic/pic9/201508/apic14052.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/group26/1515345281/src/week3/download/test/FileDownloaderTest.java b/group26/1515345281/src/week3/download/test/FileDownloaderTest.java new file mode 100644 index 0000000000..7da91ce6c6 --- /dev/null +++ b/group26/1515345281/src/week3/download/test/FileDownloaderTest.java @@ -0,0 +1,45 @@ +package week3.download.test; + +import org.junit.Test; + +import week3.download.FileDownloader; +import week3.download.api.DownloadListener; + +public class FileDownloaderTest { + + boolean downloadFinished = false; + + @Test + public void testFileDownloader() { + + /*String url = "http://210.43.133.109:9999/dldir1.qq.com/qqfile/qq/QQ8.9.1/20437/QQ8.9.1.exe"; + String localFile = "e://qq8.exe";*/ + String url="http://www.iqiyi.com/common/flashplayer/20170331/036801ea7a2e24.swf"; + String localFile="e:\\036801ea7a2e24.swf"; + long begin=System.currentTimeMillis(); + FileDownloader downloader = new FileDownloader(url, localFile); + downloader.setListener(new DownloadListener() { + + @Override + public void notifyFinished() {// + downloadFinished = true; + } + }); + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + long end=System.currentTimeMillis(); + + long cost=(end-begin)/1000; + + System.out.println("下载完成!时间为"+cost+"秒"); + } +} \ No newline at end of file diff --git a/group26/1515345281/src/week3/list/Iterator.java b/group26/1515345281/src/week3/list/Iterator.java new file mode 100644 index 0000000000..4939cb8073 --- /dev/null +++ b/group26/1515345281/src/week3/list/Iterator.java @@ -0,0 +1,5 @@ +package week3.list; +public interface Iterator{ + public boolean hasNext(); + public Object next(); +} \ No newline at end of file diff --git a/group26/1515345281/src/week3/list/LinkedList.java b/group26/1515345281/src/week3/list/LinkedList.java new file mode 100644 index 0000000000..2832694aa9 --- /dev/null +++ b/group26/1515345281/src/week3/list/LinkedList.java @@ -0,0 +1,363 @@ +package week3.list; + +import java.util.Stack; + + +public class LinkedList implements List{ + + private int size=0;//表示该链表的长度 + private Node head;//链表的头元素 + + public void add(Object o){ + if(null == head){ + head = new Node(o); + size++; + return ; + } + + Node node=head; + while(null != node.next){ + node=node.next; + } + Node addNode=new Node(o); + node.next=addNode; + size++; + } + + public void add(int index , Object o){ + if(size == 0 || index ==size){ + add(o); + return ; + } + + ListUtils.checkIndexRange(index, size); + + if(index==0){ + Node node=new Node(head.next.data); + node.next=head.next; + head.next=node; + head.data=o; + size++; + return ; + } + + Node node=head; + for(int i=0;i7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + if(null == head || null ==head.next) + return ; + + Stack stack=new Stack(); + + Node currentNode=head; + + while(currentNode!=null){ + + stack.push(currentNode); + + Node tempNode=currentNode.next; + currentNode.next=null;//断开连接 + + currentNode=tempNode; + + } + + head=stack.pop(); + currentNode=head; + + while(!stack.isEmpty()){ + + currentNode.next=stack.pop(); + currentNode=currentNode.next; + } + } + + /** + * 删除一个单链表的前半部分 + * 例如: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= size){ + throw new IndexOutOfBoundsException(); + } + + int len=size()-i>=length ? length:size-i; + + int k=0; + + while(k101->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 min && (int)head.data < max){ + head=head.next; + } + + Node cur=head; + + while(cur.next!=null){ + Node next=cur.next; + if( (int)next.data> min && (int)next.data < max){ + cur.next=next.next; + }else{ + cur=cur.next; + } + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + + LinkedList result=new LinkedList(); + Node cur=head; + int i=0; + while(cur!=null && i(int)list.get(i)){ + i++; + }else{ + cur=cur.next; + } + } + return result; + } + + 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(); + } +} \ No newline at end of file diff --git a/group26/1515345281/src/week3/list/LinkedListTest.java b/group26/1515345281/src/week3/list/LinkedListTest.java new file mode 100644 index 0000000000..7329960d49 --- /dev/null +++ b/group26/1515345281/src/week3/list/LinkedListTest.java @@ -0,0 +1,201 @@ +package week3.list; + +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(201); + list2.add(301); + list2.add(501); + + list1.subtract(list2); + + Assert.assertEquals("[101,401,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.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/group26/1515345281/src/week3/list/List.java b/group26/1515345281/src/week3/list/List.java new file mode 100644 index 0000000000..cc4a2cb261 --- /dev/null +++ b/group26/1515345281/src/week3/list/List.java @@ -0,0 +1,14 @@ +package week3.list; + +public interface List { + + public void add(Object o); + + public void add(int index, Object o); + + public Object get(int index); + + public Object remove(int index); + + public int size(); +} diff --git a/group26/1515345281/src/week3/list/ListUtils.java b/group26/1515345281/src/week3/list/ListUtils.java new file mode 100644 index 0000000000..b37e401490 --- /dev/null +++ b/group26/1515345281/src/week3/list/ListUtils.java @@ -0,0 +1,9 @@ +package week3.list; + +public class ListUtils { + + public static void checkIndexRange(int index, int size) { + if (index < 0 || index > size) + throw new IndexOutOfBoundsException(); + } +} diff --git a/group26/1515345281/src/week4/origin/jvm/loader/ClassFileLoader.java b/group26/1515345281/src/week4/origin/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..601aab6aad --- /dev/null +++ b/group26/1515345281/src/week4/origin/jvm/loader/ClassFileLoader.java @@ -0,0 +1,72 @@ +package week4.origin.jvm.loader; + +import java.io.BufferedInputStream; +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 { + + static final int BUFFER_SIZE = 1024; + private List clzPaths = new ArrayList(); + + private String path; + + public byte[] readBinaryCode(String className) { + // "week4.origin.jvm.loader.test.EmployeeV1" + String fileName = path+File.separator+className.replace(".", File.separator) + ".class"; + + FileInputStream in=null; + BufferedInputStream bis=null; + ByteArrayOutputStream baos=null; + + try { + in = new FileInputStream(fileName); + + bis = new BufferedInputStream(in, BUFFER_SIZE); + + // 缓冲区会因为数据的不断写入而自动增长 + baos = new ByteArrayOutputStream(); + + byte[] buffer = new byte[BUFFER_SIZE]; + + int len = 0; + + while ((len = bis.read(buffer)) != -1) { + baos.write(buffer, 0, len); + } + + } catch (IOException e) { + e.printStackTrace(); + }finally{ + if(bis!=null){ + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if(in!=null){ + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return baos.toByteArray(); + } + + public void addClassPath(String path) { + this.path=path; + } + + public String getClassPath() { + return path; + } +} \ No newline at end of file diff --git a/group26/1515345281/src/week4/origin/jvm/loader/LRUPageFrame.java b/group26/1515345281/src/week4/origin/jvm/loader/LRUPageFrame.java new file mode 100644 index 0000000000..104f3b8690 --- /dev/null +++ b/group26/1515345281/src/week4/origin/jvm/loader/LRUPageFrame.java @@ -0,0 +1,105 @@ +package week4.origin.jvm.loader; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private int capacity; + private int curSize;//记录当前缓存大小 + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + curSize=0; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + + if(capacity <=0 ){ + throw new IndexOutOfBoundsException(); + } + + if(curSize == 0){ + Node node=new Node(null,null,pageNum); + curSize++; + first=node; + last=node; + return ; + } + + if(first.pageNum == pageNum){ + return ; + } + + //不管是否需要置换头指针均需要改变 + Node node=new Node(null,first,pageNum); + first.prev=node; + first=node; + + if(curSize == 1){ + last.prev=node; + } + + if(curSize < capacity){ + curSize++; + return ; + } + + if(curSize == capacity){//容量不足,开始置换 + + //首先判断里面是否存在值相同元素 + Node curNode=first.next; + while(curNode.next!=null){ + if(curNode.pageNum == pageNum){//如果找到 + curNode.prev.next=curNode.next; + curNode.next.prev=curNode.prev; + return ; + } + curNode=curNode.next; + } + Node tempNode=last.prev; + last=tempNode; + last.next=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(); + } + + private static class Node { + Node prev; + Node next; + int pageNum; + public Node(Node prev,Node next,int pageNum){ + this.prev=prev; + this.next=next; + this.pageNum=pageNum; + } + } +} \ No newline at end of file diff --git a/group26/1515345281/src/week4/origin/jvm/loader/blog b/group26/1515345281/src/week4/origin/jvm/loader/blog new file mode 100644 index 0000000000..010f9cb473 --- /dev/null +++ b/group26/1515345281/src/week4/origin/jvm/loader/blog @@ -0,0 +1 @@ +SAX解析Xml实战 http://blog.csdn.net/sjshenjian/article/details/68950978 \ No newline at end of file diff --git a/group26/1515345281/src/week4/origin/jvm/loader/test/ClassFileLoaderTest.java b/group26/1515345281/src/week4/origin/jvm/loader/test/ClassFileLoaderTest.java new file mode 100644 index 0000000000..69836b7c04 --- /dev/null +++ b/group26/1515345281/src/week4/origin/jvm/loader/test/ClassFileLoaderTest.java @@ -0,0 +1,55 @@ +package week4.origin.jvm.loader.test; + +import org.junit.Assert; +import org.junit.Test; + +import week4.origin.jvm.loader.ClassFileLoader; + + +public class ClassFileLoaderTest { + + + static String path1="E:\\JAVA\\liuxin\\coding2017\\group26\\1515345281\\bin"; + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "week4.origin.jvm.loader.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1066, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "week4.origin.jvm.loader.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;iindex) {return null;} + return p.data; + } + public Object remove(int index){ + int i=1; + Node p=head; + Object o=null; + if(index==1) + { + o=head.data; + if(head.next!=null) + { + p=head.next; + head.data=p.data; + p=head; + } + else{ + head=null; + } + } + else{ + while(i7->10 , 逆置后变为 10->7->3 + */ + public void reverse() + { + if(head==null||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 length=size/2; + Node p=head; + for(int i=0;isize-1-i) return; + if(i==0) + { + removeFirst(); + for(i=1;i<=length-1;i++) + { + removeFirst(); + } + } + else{ + int j=0; + Node p=head; + while(j101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(this.size<1) return null; + if((int)(list.get(list.size))>this.size) return null; + //将链表转为数组 + int[] listToArray=new int[this.size]; + Node n=head; + for(int i=0;i actions=new HashMap<>(); + + public Configureation(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){ + 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()) + { + String resultName=resultElement.getAttributeValue("name"); + String viewName=resultElement.getText().trim(); + + ac.addViewResult(resultName, viewName); + + } + this.actions.put(actionName, ac);//把actionName以及其下面的resultName和viewName构成一个键值对 + } + } + 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.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/group26/1778842360/third homework/TTD/LoginAction.java b/group26/1778842360/third homework/TTD/LoginAction.java new file mode 100644 index 0000000000..e398f0d39a --- /dev/null +++ b/group26/1778842360/third homework/TTD/LoginAction.java @@ -0,0 +1,42 @@ +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 you user/pwd"; + return "fail"; + } + public void setName(String name) { + + this.name=name; + } + + public void setPassword(String password) { + + this.password=password; + } + public String getMessage() + { + return message; + } + +} diff --git a/group26/1778842360/third homework/TTD/ReflectionUtil.java b/group26/1778842360/third homework/TTD/ReflectionUtil.java new file mode 100644 index 0000000000..186edb6c5a --- /dev/null +++ b/group26/1778842360/third homework/TTD/ReflectionUtil.java @@ -0,0 +1,76 @@ +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"); + } + + 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 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(Exception e) + { + e.printStackTrace(); + } + } + return params; + } + +} diff --git a/group26/1778842360/third homework/TTD/ReflectionUtilTest.java b/group26/1778842360/third homework/TTD/ReflectionUtilTest.java new file mode 100644 index 0000000000..27a56433ca --- /dev/null +++ b/group26/1778842360/third homework/TTD/ReflectionUtilTest.java @@ -0,0 +1,108 @@ +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 ClassNotFoundException { + 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 actualNames=new HashSet<>(); + for(Method m:methods){ + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectedNames)); + } + @Test + public void testSetParameter() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException + { + 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 actualNames=new HashSet<>(); + for(Method m:methods) + { + actualNames.add(m.getName()); + } + Assert.assertTrue(actualNames.containsAll(expectedNames)); + } + @Test + public void testGetParmters() 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("message")); + Assert.assertEquals("test",params.get("name")); + Assert.assertEquals("123456",params.get("password")); + } + + +} diff --git a/group26/1778842360/third homework/TTD/Struts.java b/group26/1778842360/third homework/TTD/Struts.java new file mode 100644 index 0000000000..ab704cf7e9 --- /dev/null +++ b/group26/1778842360/third homework/TTD/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 Configureation cfg=new Configureation("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/group26/1778842360/third homework/TTD/View.java b/group26/1778842360/third homework/TTD/View.java new file mode 100644 index 0000000000..46138088a9 --- /dev/null +++ b/group26/1778842360/third homework/TTD/View.java @@ -0,0 +1,27 @@ +package com.coderising.litestruts; + +import java.util.Map; + +public class View { + + private String jsp; + private Map parameters; + public View setParameters(Map params) { + this.parameters=params; + return this; + } + + public View setJsp(String jsp) { + this.jsp=jsp; + return this; + } + public Map getParameters() + { + return parameters; + } + public String getJsp() + { + return jsp; + } + +} diff --git a/group26/191191717/src/week3/com/coding/download/DownloadThread.java b/group26/191191717/src/week3/com/coding/download/DownloadThread.java new file mode 100644 index 0000000000..53f77ff508 --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/DownloadThread.java @@ -0,0 +1,65 @@ +package week3.com.coding.download; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +import week3.com.coding.download.api.Connection; + +public class DownloadThread extends Thread +{ + + Connection conn; + + int startPos; + + int endPos; + + public DownloadThread(Connection conn, int startPos, int endPos) + { + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + + /** + * ִ߳з̶߳ȡһȵֽڣдļ + */ + public void run() + { + File f = new File("d:\\test.txt"); + RandomAccessFile raf = null; + try + { + raf = new RandomAccessFile(f, "rwd"); + raf.seek(startPos);// λǰָ + // raf.close(); + byte[] bs = conn.read(startPos, endPos); + raf.write(bs); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * Դͷ + * + * @param raf + * @param conn + */ + public void release(RandomAccessFile raf, Connection conn) + { + try + { + raf.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + conn.close(); + } +} diff --git a/group26/191191717/src/week3/com/coding/download/FileDownloader.java b/group26/191191717/src/week3/com/coding/download/FileDownloader.java new file mode 100644 index 0000000000..916dd3b13f --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/FileDownloader.java @@ -0,0 +1,145 @@ +package week3.com.coding.download; + +import java.io.IOException; + +import week3.com.coding.download.api.Connection; +import week3.com.coding.download.api.ConnectionException; +import week3.com.coding.download.api.ConnectionManager; +import week3.com.coding.download.api.DownloadListener; +import week3.com.coding.download.impl.ConnectionImpl; +import week3.com.coding.download.impl.ConnectionManagerImpl; + +public class FileDownloader +{ + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + int ThreadNum; + + public FileDownloader(String url, int threadNum) + { + super(); + this.url = url; + 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 = (ConnectionImpl)cm.open(this.url); + int length = conn.getContentLength();// 获取文件的长度 + // 三个线程,每个线程下载长度要平均 + int blockSize = length / this.ThreadNum; + for (int i = 1; i <= this.ThreadNum; i++) + { + int sPos = (i - 1) * blockSize; + int ePos = i * blockSize - 1; + // 如果是最后一个,则结束位置等于最后的地方 + if (i == this.ThreadNum) + { + ePos = length; + } + new DownloadThread(conn, sPos, ePos).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; + } + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public ConnectionManager getCm() + { + return cm; + } + + public void setCm(ConnectionManager cm) + { + this.cm = cm; + } + + public int getThreadNum() + { + return ThreadNum; + } + + public void setThreadNum(int threadNum) + { + ThreadNum = threadNum; + } + + public static void main(String[] args) + throws ConnectionException, IOException + { + + String url = "http://localhost:8088/JSPDemo/test.txt"; + // ConnectionImpl ci=(ConnectionImpl)cm.open(url); + // System.out.println(new String(ci.read(2, 31))); + // File f = new File("d:\\test.txt"); + // RandomAccessFile raf = new RandomAccessFile(f, "rwd"); + // raf.seek(raf.length());// 定位当前的指针 + + FileDownloader downloader = new FileDownloader(url,3); + downloader.setConnectionManager(new ConnectionManagerImpl()); + downloader.execute(); + // int length = conn.getContentLength();// 获取文件的长度 + // System.out.println("urlConn: " + length); + // int blockSize = length / 3; + + // new DownloadThread(conn, 0, blockSize - 1).start();// 第一个线程 + // new DownloadThread(conn, blockSize, blockSize * 2 - 1).start();// 第二个线程 + // new DownloadThread(conn, blockSize * 2 , length - 1).start();// 第三个线程 + } +} diff --git a/group26/191191717/src/week3/com/coding/download/FileDownloaderTest.java b/group26/191191717/src/week3/com/coding/download/FileDownloaderTest.java new file mode 100644 index 0000000000..44dadbdd4a --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/FileDownloaderTest.java @@ -0,0 +1,66 @@ +package week3.com.coding.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import week3.com.coding.download.api.ConnectionManager; +import week3.com.coding.download.api.DownloadListener; +import week3.com.coding.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:8088/JSPDemo/test.txt"; + + FileDownloader downloader = new FileDownloader(url,3); + 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/group26/191191717/src/week3/com/coding/download/api/Connection.java b/group26/191191717/src/week3/com/coding/download/api/Connection.java new file mode 100644 index 0000000000..8d664048df --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/api/Connection.java @@ -0,0 +1,28 @@ +package week3.com.coding.download.api; + +import java.io.IOException; + +public interface Connection +{ + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos, int endPos) + throws IOException; + + /** + * 得到数据内容的长度 + * + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} \ No newline at end of file diff --git a/group26/191191717/src/week3/com/coding/download/api/ConnectionException.java b/group26/191191717/src/week3/com/coding/download/api/ConnectionException.java new file mode 100644 index 0000000000..5a5dfb8986 --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package week3.com.coding.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group26/191191717/src/week3/com/coding/download/api/ConnectionManager.java b/group26/191191717/src/week3/com/coding/download/api/ConnectionManager.java new file mode 100644 index 0000000000..508c9cfd6b --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package week3.com.coding.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group26/191191717/src/week3/com/coding/download/api/DownloadListener.java b/group26/191191717/src/week3/com/coding/download/api/DownloadListener.java new file mode 100644 index 0000000000..88fb30cf93 --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/api/DownloadListener.java @@ -0,0 +1,6 @@ +package week3.com.coding.download.api; + +public interface DownloadListener +{ + public void notifyFinished(); +} diff --git a/group26/191191717/src/week3/com/coding/download/impl/ConnectionImpl.java b/group26/191191717/src/week3/com/coding/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..cf03537556 --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/impl/ConnectionImpl.java @@ -0,0 +1,70 @@ +package week3.com.coding.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +import week3.com.coding.download.api.Connection; + +public class ConnectionImpl implements Connection +{ + HttpURLConnection conn; + + public ConnectionImpl() + { + } + + public ConnectionImpl(HttpURLConnection urlConn) + { + this.conn = urlConn; + } + + public HttpURLConnection getConn() + { + return conn; + } + + public void setConn(HttpURLConnection conn) + { + this.conn = conn; + } + + @Override + public byte[] read(int startPos, int endPos) + throws IOException + { + System.out.println("startPos: " + startPos + " endPos " + endPos); + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + (endPos + 1)); + InputStream is = conn.getInputStream(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buff = new byte[1024]; + int len = 0; + while ((len = is.read(buff)) != -1) + { + out.write(buff, 0, len); + } + byte[] bs = out.toByteArray(); + return bs; + } + + /** + * ȡļij + */ + @Override + public int getContentLength() + { + + return conn == null ? 0 : conn.getContentLength(); + } + + @Override + public void close() + { + if (conn != null) + { + conn.disconnect(); + } + } + +} diff --git a/group26/191191717/src/week3/com/coding/download/impl/ConnectionManagerImpl.java b/group26/191191717/src/week3/com/coding/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..8a09013c3e --- /dev/null +++ b/group26/191191717/src/week3/com/coding/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,42 @@ +package week3.com.coding.download.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import week3.com.coding.download.api.Connection; +import week3.com.coding.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager +{ + /** + * һurl , һ + * + * @param url + * @return + */ + @Override + public Connection open(String url) + { + Connection conn=null; + URL httpUrl = null; + HttpURLConnection urlConn = null; + try + { + httpUrl = new URL(url); + urlConn = (HttpURLConnection)httpUrl.openConnection(); + } + catch (MalformedURLException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + conn= new ConnectionImpl(urlConn); + return conn; + } + +} diff --git a/group26/2441547139/week1/collection/MyArrayList.java b/group26/2441547139/week1/collection/MyArrayList.java new file mode 100644 index 0000000000..979ee23d8c --- /dev/null +++ b/group26/2441547139/week1/collection/MyArrayList.java @@ -0,0 +1,65 @@ +package week1.collection; + +import java.util.Arrays; +/** + * Created by zndbl on 2017/3/11. + */ +public class MyArrayList { + + private int size; + private Object[] arr; + + public MyArrayList() { + this(10); + } + + public MyArrayList(int oldLength) { + if(oldLength < 0) { + throw new RuntimeException("创建集合失败"); + } + arr = new Object[oldLength]; + } + + public int size() { + return size; + } + + /** + * 数组的长度扩充策略 + */ + public void ensureCapacity(int minCapatity ) { + int oldCapacity = arr.length; + if(minCapatity > oldCapacity) { + int newCapatity = 3 * oldCapacity / 2 + 1; + if(minCapatity > newCapatity) { + newCapatity = minCapatity; + } + arr = Arrays.copyOf(arr,newCapatity); + } + } + + public void add(Object element) { + ensureCapacity(size+1); + arr[size++] = element; + } + + public void add(int index, Object element) { + if(index < 0 || index > size) { + throw new RuntimeException("数组越界"); + } + ensureCapacity(size+1); + System.arraycopy(arr,index,arr,index+1,size-index); + arr[index] = element; + size++; + } + + public boolean remove(Object o) { + for(int i=0; i index ; i--) { + cussor = cussor.prev; + } + return cussor; + } + } + + public Object get(int index) { + checkRange(index); + return node(index).item; + } + + public void checkRange(int index) { + if(index >= size || index < 0) { + throw new RuntimeException("index超过界限"); + } + } + + public int indexOf(Object element) { + Node cussor = first; + int count = 0; + while (cussor != null) { + if(element.equals(cussor.item)) { + return count; + } + count++; + cussor = cussor.next; + } + return -1; + } + + public boolean remove(Object o) { + int index = indexOf(o); + if(index < 0) { + return false; + } + deleteLink(index); + return true; + } + + public Object deleteLink(int index) { + Node l = node(index); + Object item = l.item; + Node prevNode = l.prev; + Node nextNode = l.next; + + if(prevNode == null) { + first = nextNode; + } else { + prevNode.next = nextNode; + l.next = null; + } + if(nextNode == null) { + last = prevNode; + } else { + nextNode.prev = prevNode; + l.prev = null; + } + size--; + l.item = null; + return item; + + } + + +} diff --git a/group26/2441547139/week1/collection/MyQueue.java b/group26/2441547139/week1/collection/MyQueue.java new file mode 100644 index 0000000000..2721b305a7 --- /dev/null +++ b/group26/2441547139/week1/collection/MyQueue.java @@ -0,0 +1,29 @@ +package week1.collection; + +/** + * Created by zndbl on 2017/3/12. + */ +public class MyQueue { + + private Object[] data; + private int head; + private int tail; + + public MyQueue() { + data = new Object[10]; + head = 1; + tail = 1; + } + + public void put(Object obj) { + data[tail] = obj; + tail++; + } + + public Object get() { + Object obj = data[head]; + head++; + return obj; + } + +} diff --git a/group26/2441547139/week1/collection/MyStack.java b/group26/2441547139/week1/collection/MyStack.java new file mode 100644 index 0000000000..1b2b8c5d2c --- /dev/null +++ b/group26/2441547139/week1/collection/MyStack.java @@ -0,0 +1,29 @@ +package week1.collection; + +/** + * Created by zndbl on 2017/3/12. + */ +public class MyStack { + + private Object[] data; + private int top; + + public MyStack() { + data = new Object[100]; + top = -1; + } + + public void put(Object t) { + data[data.length] = t; + top++; + } + + public Object pop() { + if(top < 0) { + return null; + } + Object object = data[top]; + top--; + return object; + } +} diff --git a/group26/2441547139/week2/arrayutil/ArrayUtils.java b/group26/2441547139/week2/arrayutil/ArrayUtils.java new file mode 100644 index 0000000000..5bb9f6582f --- /dev/null +++ b/group26/2441547139/week2/arrayutil/ArrayUtils.java @@ -0,0 +1,172 @@ +package week2.arrayutil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by zndbl on 2017/3/23. + */ +public class ArrayUtils { + + public static void main(String[] args) { +// int[] oldArray = new int[]{4,6,2,1,0,5,0,8}; +// int[] newArray = reverseArray(oldArray); +// int[] newArray = removeZero(oldArray); +// String array = "["; +// for(int i = 0 ; i < newArray.length ; i++) { +// array += newArray[i]; +// } +// array += "]"; +// System.out.println(array); +// String s = seperatorArray(oldArray); +// System.out.println(s); +// List math = getAllMath(6); +// int[] array = getPrimeArray(23); +// printArray(array); + getFibonacci(15); + } + + public static void printArray(int[] newArray) { + String array = "["; + for (int i = 0; i < newArray.length; i++) { + array += (newArray[i]+","); + } + array += "]"; + System.out.println(array); + } + + /** + * 数组的反转 + * + * @param oldArray + * @return + */ + public static int[] reverseArray(int[] oldArray) { + int[] newArray = new int[oldArray.length]; + for (int i = 0; i < (oldArray.length); i++) { + newArray[i] = oldArray[oldArray.length - 1 - i]; + } + return newArray; + } + + /** + * 清除数组中的元素0 + * + * @param array + * @return + */ + public static int[] removeZero(int[] array) { + int[] newArray = new int[array.length]; + int j = 0; + for (int i = 0; i < array.length; i++) { + if (array[i] != 0) { + newArray[j++] = array[i]; + } + } + System.out.println(j); + Arrays.copyOf(newArray, j); + return newArray; + } + + /** + * 连接字符 + * + * @param oldArray + * @return + */ + public static String seperatorArray(int[] oldArray) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < oldArray.length; i++) { + if (i == oldArray.length - 1) { + sb.append(oldArray[i]); + break; + } + sb.append(oldArray[i]).append("_"); + } + return sb.toString(); + } + + /** + * 传100,求小于100的所有完数 + * + * @param old + * @return + */ + public static List getAllMath(int old) { + List list = new ArrayList<>(); + int count = 0; + for (int i = 1; i <= old - 1; i++) { + if (old % i == 0) { + System.out.println(i); + count = count + i; + list.add(i); + } + } + if (count == old) { + return list; + } + return new ArrayList(); + } + + /** + * 返回所有小于给定数的素数数组 + * + * @param old + * @return + */ + public static int[] getPrimeArray(int old) { + int[] primeArray = new int[old]; + int k = 0; + for (int i = 1; i < old; i++) { + if (isPrime(i)) { + primeArray[k] = i; + k++; + } + } + return Arrays.copyOf(primeArray, k ); + } + + /** + * 判断一个数是不是素数 + * + * @param i + * @return + */ + public static boolean isPrime(int i) { + int count = 0; + for (int j = 1; j <= i; j++) { + if (i % j == 0) { + count++; + } + } + if (count > 2 || count == 1) { + return false; + } + return true; + } + + /** + * 小于给定数的斐波那契数列 + * 传进去15,1 1 2 3 5 8 13 + * @param old + * @return + */ + public static void getFibonacci(int old) { + int first = 1; + int second = 1; + int num = add(first, second, old); + System.out.println(num); + } + + public static int add(int first, int second, int old) { + int last = first + second; + int before = second; + if(last > old) { + return before; + } + return add(before, last, old); + } + + +} diff --git a/group26/2441547139/week2/struts/LoginAction.java b/group26/2441547139/week2/struts/LoginAction.java new file mode 100644 index 0000000000..b7bf1adc62 --- /dev/null +++ b/group26/2441547139/week2/struts/LoginAction.java @@ -0,0 +1,39 @@ +package week2.struts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @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/group26/2441547139/week2/struts/LoginOutAction.java b/group26/2441547139/week2/struts/LoginOutAction.java new file mode 100644 index 0000000000..450d158339 --- /dev/null +++ b/group26/2441547139/week2/struts/LoginOutAction.java @@ -0,0 +1,5 @@ +package week2.struts; + +public class LoginOutAction { + +} diff --git a/group26/2441547139/week2/struts/Struts.java b/group26/2441547139/week2/struts/Struts.java new file mode 100644 index 0000000000..ddc5509539 --- /dev/null +++ b/group26/2441547139/week2/struts/Struts.java @@ -0,0 +1,74 @@ +package week2.struts; + + +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import java.io.File; +import java.util.List; + +public class Struts { + + public static void main(String[] args) { + runAction(); + } + + public static void runAction() { + + /* + + 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字段中。 + + */ + File file = new File("src/week2/struts/struts.xml"); + SAXReader saxReader = new SAXReader(); + try { + Document document = saxReader.read(file); + Element rootElement = document.getRootElement(); +// List elements = rootElement.elements("action"); +// for (Element element : elements) { +// String aClass = element.attributeValue("class"); +// Class firstClass = Class.forName(aClass); +// Object obj = firstClass.newInstance(); +// Method setName = firstClass.getMethod("setName",String.class); +// Method setPassWord = firstClass.getMethod("setPassword",String.class); +// Method execute = firstClass.getMethod("execute"); +// setName.invoke(obj , "test"); +// setPassWord.invoke(obj , "1234"); +// String result = (String) execute.invoke(obj); +// System.out.println(result); +// } + //根节点的子节点 + List elements = rootElement.elements(); + for(Element element : elements) { + //节点的属性 + List attributes = element.attributes(); + List list = element.elements(); + for(Element e : list) { + if(e.attributeValue("name").equals("success")) { + String jsp = e.getTextTrim(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/group26/2441547139/week2/struts/View.java b/group26/2441547139/week2/struts/View.java new file mode 100644 index 0000000000..2b8c86c49f --- /dev/null +++ b/group26/2441547139/week2/struts/View.java @@ -0,0 +1,23 @@ +package week2.struts; + +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/group26/2441547139/week3/linkedlist/MyLinkedLists.java b/group26/2441547139/week3/linkedlist/MyLinkedLists.java new file mode 100644 index 0000000000..dfd299dae6 --- /dev/null +++ b/group26/2441547139/week3/linkedlist/MyLinkedLists.java @@ -0,0 +1,272 @@ +package week3.linkedlist; + +import java.util.Iterator; + +/** + * Created by zndbl on 2017/3/29. + */ +public class MyLinkedLists { + + private Node head; + private int size; + + /** + * 删除第一个 + * + * @return + */ + public Node removeFirst() { + Node node = head; + head = node.getNext(); + size--; + return node; + } + + /** + * 删除最后一个 + * + * @return + */ + public Node removeLast() { + Node node = head; + Node pre = null; + while (node != null) { + pre = node; + node = node.getNext(); + } + pre.setNext(null); + size--; + return pre; + } + + /** + * 新增节点在第一个 + * + * @param data + */ + public void addFirst(Object data) { + Node node = new Node(data); + node.setNext(head); + head = node; + size++; + } + + /** + * 得到指定索引的节点 + * + * @param index + * @return + */ + public Node getNode(int index) { + index++; + Node node = null; + for (int i = 0; i < index; i++) { + node = head; + node = node.getNext(); + } + return head; + } + + /** + * 删除指定索引的节点 + * + * @param index + * @return + */ + public Node removeNode(int index) { + Node prevNode = getNode(index--); + Node currNode = getNode(index); + Node succNode = currNode.getNext(); + prevNode.setNext(succNode); + currNode = null; + size--; + return succNode; + } + + /** + * 在最后添加一个节点 + * + * @return + */ + public Node addLast(Object data) { + Node node = new Node(data); + Node curr = head; + Node succ = null; + while (curr != null) { + succ = curr; + curr = curr.getNext(); + } + succ.setNext(node); + size++; + return node; + } + + /** + * 在指定索引增加 + * + * @param index + * @param obj + */ + public void add(int index, Object obj) { + Node curr = head; + Node prev = null; + while (curr != null) { + if (index == 0) { + break; + } + prev = curr; + curr = curr.getNext(); + index--; + } + if (prev != null) { + Node node = new Node(obj); + node.setNext(curr); + prev.setNext(node); + } + } + + /** + * 得到大小 + * + * @return + */ + public int size() { + return size; + } + + /** + * 得到迭代器 + * + * @return + */ + public Iterator iterator() { + return new MyLinkedListsIterator(this); + } + + /** + * 反转节点 + */ + public void reverse() { + Node prev = null; + Node next = null; + Node curr = head; + while (curr != null) { + next = curr.getNext(); + curr.setNext(prev); + prev = curr; + curr = next; + } + head = prev; + } + + /** + * 链表头一半删除 + */ + public void removeFirstHalf() { + Node curr = head; + int half = size / 2; + while (half != 0) { + curr = curr.getNext(); + half--; + } + head = curr; + } + + /** + * 指定索引,指定长度的删除 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + if (i + length >= size - 1) { + length = size - 1 - i; + } + int count = i; + Node pre = null; + Node curr = head; + while (curr != null) { + if (count == 0) { + break; + } + pre = curr; + curr = curr.getNext(); + count--; + } + while (curr != null) { + if (length == 0) { + break; + } + curr = curr.getNext(); + length--; + } + pre.setNext(curr.getNext()); + + } + + /** + * 打印方法 + * @return + */ + public String toString() { + StringBuilder builder = new StringBuilder(); + Node current = head; + while (current == null) { + builder.append(current.toString()); + current = current.getNext(); + } + return builder.toString(); + } + + private class MyLinkedListsIterator implements Iterator { + + private MyLinkedLists linkedList; + private int length = 0; + + public MyLinkedListsIterator(MyLinkedLists linkedList) { + this.linkedList = linkedList; + } + + @Override + public boolean hasNext() { + return length < size; + } + + @Override + public Object next() { + return linkedList.getNode(length++); + } + + @Override + public void remove() { + linkedList.removeNode(length--); + } + } + + + public static class Node { + + private Object data; + private Node next; + + public Node(Object data) { + this.data = data; + } + + public void setNext(Node next) { + this.next = next; + } + + public Node getNext() { + return next; + } + + public Object getData() { + return this.data; + } + + public String toString() { + return "data = "+data; + } + } +} diff --git a/group26/2441547139/week3/thread/DownloadThread.java b/group26/2441547139/week3/thread/DownloadThread.java new file mode 100644 index 0000000000..f6ea4ae09f --- /dev/null +++ b/group26/2441547139/week3/thread/DownloadThread.java @@ -0,0 +1,67 @@ +package week3.thread; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.CountDownLatch; + +public class DownloadThread extends Thread { + + private File file; + private CountDownLatch countDownLatch; + private String address; + private int startPos; + private int endPos; + + public DownloadThread(File file, CountDownLatch countDownLatch, + String address, int startPos, int endPos) { + super(); + this.file = file; + this.countDownLatch = countDownLatch; + this.address = address; + this.startPos = startPos; + this.endPos = endPos; + } + + public void run() { + Thread current = Thread.currentThread(); + System.out.println(current.getName() + "开始下载:" + startPos + "-" + + endPos); + RandomAccessFile randomAccessFile = null; + InputStream inputStream = null; + try { + URL url = new URL(address); + HttpURLConnection httpURLConnection = (HttpURLConnection) url + .openConnection(); + httpURLConnection.setRequestProperty("Range", "bytes=" + startPos + + "-" + endPos); + inputStream = httpURLConnection.getInputStream(); + randomAccessFile = new RandomAccessFile(file, "rw"); + randomAccessFile.seek(startPos); + byte[] bytes = new byte[1024]; + int read = 0; + while ((read = inputStream.read(bytes)) != -1) { + randomAccessFile.write(bytes, 0, read); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (randomAccessFile != null) { + randomAccessFile.close(); + } + if (inputStream != null) { + inputStream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println(current.getName() + "下载完成"); + countDownLatch.countDown(); + } + + } +} \ No newline at end of file diff --git a/group26/2441547139/week3/thread/FileDownload.java b/group26/2441547139/week3/thread/FileDownload.java new file mode 100644 index 0000000000..7dd7df1a28 --- /dev/null +++ b/group26/2441547139/week3/thread/FileDownload.java @@ -0,0 +1,53 @@ +package week3.thread; + +import java.io.File; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.CountDownLatch; + +public class FileDownload { + + private String address; + + public FileDownload(String address) { + this.address = address; + } + + public void download(int threadCount) { + try { + URL url = new URL(address); + HttpURLConnection httpURLConnection = (HttpURLConnection) url + .openConnection(); + int length = httpURLConnection.getContentLength(); + System.out.println("文件大小:"+length); + File file = new File("D:\\download.jpg"); + CountDownLatch countDownLatch = new CountDownLatch(threadCount); + // 计算每个线程下载的数据大小 + int blockSize = length / threadCount; + for (int i = 0; i < threadCount; i++) { + int startPos = blockSize * i; + int endPos = blockSize * (i + 1); + if (i == threadCount - 1) { + //最后一个下载剩下的 + endPos = length; + } + new DownloadThread(file, countDownLatch, address, startPos, + endPos - 1).start(); + } + while (countDownLatch.getCount() != 0) { + System.out.println("下载中...."); + try { + // 休眠 + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成"); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/group26/2441547139/week3/thread/ThreadDownload.java b/group26/2441547139/week3/thread/ThreadDownload.java new file mode 100644 index 0000000000..7e09e4f843 --- /dev/null +++ b/group26/2441547139/week3/thread/ThreadDownload.java @@ -0,0 +1,35 @@ +package week3.thread; + +/** + * Created by zndbl on 2017/3/26. + */ +public class ThreadDownload { + + public static void main(String[] args) { +// //单线程下载 +// try { +// String url = "http://img.alicdn.com/bao/uploaded/i2/412712826/TB2eNIZXXYC11BjSspfXXXcPFXa_!!412712826.jpg_240x240.jpg"; +// HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); +// conn.setRequestMethod("GET"); +// conn.setReadTimeout(5000); +// conn.setConnectTimeout(5000); +// InputStream in = conn.getInputStream(); +// BufferedInputStream bufferedInputStream = new BufferedInputStream(in); +// File file = new File("D:/a.jpg"); +// BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file)); +// byte[] buffer = new byte[1024]; +// int len = -1; +// while ((len = bufferedInputStream.read(buffer)) != -1) { +// bufferedOutputStream.write(buffer, 0, len); +// bufferedOutputStream.flush(); +// } +// } catch (Exception e) {ScheduledThreadPoolExecutor +// e.printStackTrace(); +// } + + //多线程部分参考网上的 + String url = "http://wx.qlogo.cn/mmopen/fqCl7qHPjf2JaKGXwqRe3WoMwnBouoSNG2Xd3kYAcfLEmibXEpZH9HVDyDiassfPgiav8kx9wNDypGxaibxdQFIXzIhib2N2ibuo07/0"; + FileDownload fileDownload = new FileDownload(url); + fileDownload.download(3); + } +} diff --git "a/group26/2441547139/\346\234\211\351\201\223\347\254\224\350\256\260.txt" "b/group26/2441547139/\346\234\211\351\201\223\347\254\224\350\256\260.txt" new file mode 100644 index 0000000000..31173ac162 --- /dev/null +++ "b/group26/2441547139/\346\234\211\351\201\223\347\254\224\350\256\260.txt" @@ -0,0 +1,3 @@ +http://note.youdao.com/noteshare?id=63cfdc5e194deb6458f9733681088516 +http://note.youdao.com/noteshare?id=3078d5c9a9f86e590973ee40ba3fdb25 +http://note.youdao.com/noteshare?id=8fb7ea6223b152c647f09dc98882751b lucene򵥽 diff --git "a/group26/26\347\273\204\346\203\205\345\206\265\347\273\237\350\256\241.md" "b/group26/26\347\273\204\346\203\205\345\206\265\347\273\237\350\256\241.md" index 165922cc87..463477e992 100644 --- "a/group26/26\347\273\204\346\203\205\345\206\265\347\273\237\350\256\241.md" +++ "b/group26/26\347\273\204\346\203\205\345\206\265\347\273\237\350\256\241.md" @@ -11,7 +11,7 @@ | | | | | | | | 2070509107 | 已完成 | | | | | | | | | | | | -| lizhy2017 | 部分完成 | 已完成 | | | | +| lizhy2017           |                   已完成                   |   已完成 |     |  已完成   |     | | | | | | | | | JEE-逆水百川 | 部分完成 | | | | | | | http://blog.csdn.net/u012759397/article/details/61618612 | | | | | diff --git a/group26/723161901/jvm/loader/ClassFileLoader.java b/group26/723161901/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..a87ca911dd --- /dev/null +++ b/group26/723161901/jvm/loader/ClassFileLoader.java @@ -0,0 +1,63 @@ +package com.jvm.loader; + +import java.io.BufferedInputStream; +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 { + File f = new File(clzPaths.get(0)+File.separatorChar+className+".class"); + if(!f.exists()){ + throw new FileNotFoundException("File not found"); + } + ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length()); + BufferedInputStream in = null; + try { + in = new BufferedInputStream(new FileInputStream(f)); + int buf_size = 1024; + byte[] buffer = new byte[buf_size]; + int len = 0; + while(-1 != (len = in.read(buffer, 0, buf_size))){ + bos.write(buffer, 0, len); + } + return bos.toByteArray(); + } catch (Exception e) { + e.printStackTrace(); + }finally { + try { + in.close(); + } catch (Exception e2) { + e2.printStackTrace(); + } + bos.close(); + } + return null; + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + + public String getClassPath(){ + String results = ""; + for (int i = 0; i < clzPaths.size(); i++) { + results += clzPaths.get(i); + if(i!=clzPaths.size()-1){ + results += ";"; + } + } + return results; + } + +} diff --git a/group26/723161901/jvm/test/ClassFileloaderTest.java b/group26/723161901/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..bd835c3857 --- /dev/null +++ b/group26/723161901/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,94 @@ +package com.jvm.test; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + static String path1 = "/Users/Macx/Workspaces/coding2017/mini-jvm/bin/com/jvm/test"; + static String path2 = "/Users/Macx/Workspaces/coding2017/mini-jvm/bin/com/jvm/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 = "EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1034, byteCodes.length); + + } + + + @Test + public void testMagicNumber() throws IOException{ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "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() { + try { + URLConnection con = url.openConnection(); + return con.getContentLength(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + + + } + +} diff --git a/group26/723161901/src/com/download/download/impl/ConnectionManagerImpl.java b/group26/723161901/src/com/download/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..acb0c3ea38 --- /dev/null +++ b/group26/723161901/src/com/download/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.impl; + +import com.api.Connection; +import com.api.ConnectionException; +import com.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String urlStr) throws ConnectionException { + + return new ConnectionImpl(urlStr); + } + +} diff --git a/group26/723161901/src/com/litestruts/LoginAction.java b/group26/723161901/src/com/litestruts/LoginAction.java new file mode 100644 index 0000000000..b27743e9a8 --- /dev/null +++ b/group26/723161901/src/com/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package com.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/group26/723161901/src/com/litestruts/Struts.java b/group26/723161901/src/com/litestruts/Struts.java new file mode 100644 index 0000000000..51cb708e26 --- /dev/null +++ b/group26/723161901/src/com/litestruts/Struts.java @@ -0,0 +1,91 @@ +package com.litestruts; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.litestruts.strutsBean.Action; + + + +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字段中。 + + */ + StrutsXmlReader strutsXml = new StrutsXmlReader(new File("src/com/litestruts/struts.xml")); + View view = new View(); + try { + HashMap actMap = (HashMap) strutsXml.loadXml(); + Action act = (Action) actMap.get(actionName); + Class clazz = Class.forName(act.getClazz()); + Object obj = clazz.newInstance(); + HashMap paraMap = act.getParameters(); + Iterator> iteraPara = parameters.entrySet().iterator(); + + while(iteraPara.hasNext()){ + Entry itera = iteraPara.next(); + Field field = clazz.getDeclaredField(itera.getKey()); + field.setAccessible(true); + field.set(obj, itera.getValue()); + } + + Method method = clazz.getMethod("execute", null); + String results = (String)method.invoke(obj, null); + Field[] getFields = clazz.getDeclaredFields(); + HashMap getMapPara = new HashMap(); + for (Field field : getFields) { + field.setAccessible(true); + String getFiledName = field.getName(); + Object objValue = field.get(obj); + getMapPara.put(getFiledName, objValue); + } + + view.setParameters(getMapPara); + view.setJsp((String)paraMap.get(results)); + + } catch (Exception e) { + e.printStackTrace(); + } + + return view; + } + + +} diff --git a/group26/723161901/src/com/litestruts/StrutsTest.java b/group26/723161901/src/com/litestruts/StrutsTest.java new file mode 100644 index 0000000000..48614832d0 --- /dev/null +++ b/group26/723161901/src/com/litestruts/StrutsTest.java @@ -0,0 +1,41 @@ +package com.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(); + + 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/group26/723161901/src/com/litestruts/StrutsXmlReader.java b/group26/723161901/src/com/litestruts/StrutsXmlReader.java new file mode 100644 index 0000000000..6470bc1d96 --- /dev/null +++ b/group26/723161901/src/com/litestruts/StrutsXmlReader.java @@ -0,0 +1,59 @@ +package com.litestruts; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +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.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.litestruts.strutsBean.Action; + +public class StrutsXmlReader { + private File file; + private HashMap actMap = new HashMap(); + + public StrutsXmlReader(File file) { + super(); + this.file = file; + } + + + public Map loadXml() throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(file); + NodeList nl = doc.getElementsByTagName("action"); + for (int i = 0; i < nl.getLength(); i++) { + Element book = (Element) nl.item(i); + String name = book.getAttribute("name"); + String claz = book.getAttribute("class"); + Action act = new Action(name, claz); + System.out.println(name); + System.out.println(claz); + NodeList bookNode = book.getChildNodes(); + HashMap paraMap = new HashMap(); + for (int j = 0; j < bookNode.getLength(); j++) { + Node bookCh = bookNode.item(j); + if (bookCh.getNodeType() == Node.ELEMENT_NODE) { + String valTag = bookCh.getTextContent(); + NamedNodeMap attrs = bookCh.getAttributes(); + String resultsValue = attrs.getNamedItem("name").getNodeValue(); + paraMap.put(resultsValue, valTag); + } + act.setParameters(paraMap); + } + actMap.put(act.getName(), act); + } + return actMap; + } +} diff --git a/group26/723161901/src/com/litestruts/View.java b/group26/723161901/src/com/litestruts/View.java new file mode 100644 index 0000000000..af63dce301 --- /dev/null +++ b/group26/723161901/src/com/litestruts/View.java @@ -0,0 +1,23 @@ +package com.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/group26/723161901/src/com/litestruts/strutsBean/Action.java b/group26/723161901/src/com/litestruts/strutsBean/Action.java new file mode 100644 index 0000000000..37435653f2 --- /dev/null +++ b/group26/723161901/src/com/litestruts/strutsBean/Action.java @@ -0,0 +1,46 @@ +package com.litestruts.strutsBean; + +import java.util.HashMap; + +public class Action { + private String name; + private String clazz; + private HashMap parameters; + + public Action() { + super(); + } + + public Action(String name, String clazz) { + super(); + this.name = name; + this.clazz = clazz; + } + + public Action(String name, String clazz, HashMap parameters) { + super(); + this.name = name; + this.clazz = clazz; + this.parameters = parameters; + } + 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 HashMap getParameters() { + return parameters; + } + public void setParameters(HashMap parameters) { + this.parameters = parameters; + } + + +} diff --git a/group26/89460886/src/week03/source/download/DownloadThread.java b/group26/89460886/src/week03/source/download/DownloadThread.java new file mode 100644 index 0000000000..75ba05c62b --- /dev/null +++ b/group26/89460886/src/week03/source/download/DownloadThread.java @@ -0,0 +1,40 @@ +package coding.coderising.download; + +import coding.coderising.download.api.Connection; + +import java.io.IOException; + +/** + * @author jiaxun + */ +public class DownloadThread extends Thread{ + + private Connection connection; + private int startPos; + private int endPos; + private byte[] downloadByte; + + public DownloadThread(Connection connection, int startPos, int endPos) { + this.connection = connection; + this.startPos = startPos; + this.endPos = endPos; + } + + @Override + public void run() { + try { + downloadByte = connection.read(startPos, endPos); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public byte[] getDownloadByte() { + return downloadByte; + } + + public int getStartPos() { + return startPos; + } + +} diff --git a/group26/89460886/src/week03/source/download/FileDownloader.java b/group26/89460886/src/week03/source/download/FileDownloader.java new file mode 100644 index 0000000000..9cf09cbd40 --- /dev/null +++ b/group26/89460886/src/week03/source/download/FileDownloader.java @@ -0,0 +1,101 @@ +package coding.coderising.download; + +import coding.coderising.download.api.Connection; +import coding.coderising.download.api.ConnectionManager; +import coding.coderising.download.api.DownloadListener; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; + +/** + * @author jiaxun + */ +public class FileDownloader { + + private static final int THREAD_COUNT = 3; + + private int threadCount; + private String downloadUrl; + private DownloadListener downloadListener; + private ConnectionManager connectionManager; + private String savePath; + + public FileDownloader(String downloadUrl, String savePath) { + this.downloadUrl = downloadUrl; + this.savePath = savePath; + this.threadCount = THREAD_COUNT; + } + + public void execute() { + Connection connection = null; + RandomAccessFile out = null; + try { + connection = connectionManager.open(downloadUrl); + int length = connection.getContentLength(); + connection.close(); + + int downloadOffset = 0; + List threadList = new ArrayList<>(); + for (int i = 0; i < threadCount; i++) { + DownloadThread thread = new DownloadThread(connectionManager.open(downloadUrl), downloadOffset, downloadOffset + (i + 1) * (length / threadCount)); + threadList.add(thread); + thread.start(); + downloadOffset = (i + 1) * (length / threadCount) + 1; + } + if (downloadOffset < length) { + DownloadThread thread = new DownloadThread(connectionManager.open(downloadUrl), downloadOffset, length - 1); + threadList.add(thread); + thread.start(); + } + + for (DownloadThread thread : threadList) { + thread.join(); + } + + File file = new File(savePath); + out = new RandomAccessFile(file, "rwd"); + for (DownloadThread thread : threadList) { + out.seek(thread.getStartPos()); + out.write(thread.getDownloadByte()); + } + + if (downloadListener != null) { + downloadListener.notifyFinished(); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (connection != null) { + connection.close(); + } + try { + if (out != null) { + out.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void setConnectionManager(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + + public void setDownloadListener(DownloadListener downloadListener) { + this.downloadListener = downloadListener; + } + + public DownloadListener getDownloadListener() { + return this.downloadListener; + } + + public void setThreadCount(int threadCount) { + this.threadCount = threadCount; + } + +} diff --git a/group26/89460886/src/week03/source/download/api/Connection.java b/group26/89460886/src/week03/source/download/api/Connection.java new file mode 100644 index 0000000000..59db422b34 --- /dev/null +++ b/group26/89460886/src/week03/source/download/api/Connection.java @@ -0,0 +1,16 @@ +package coding.coderising.download.api; + +import java.io.IOException; + +/** + * @author jiaxun + */ +public interface Connection { + + byte[] read(int startPos, int endPos) throws IOException; + + int getContentLength(); + + void close(); + +} diff --git a/group26/89460886/src/week03/source/download/api/ConnectionException.java b/group26/89460886/src/week03/source/download/api/ConnectionException.java new file mode 100644 index 0000000000..1e1b2a3299 --- /dev/null +++ b/group26/89460886/src/week03/source/download/api/ConnectionException.java @@ -0,0 +1,10 @@ +package coding.coderising.download.api; + +/** + * @author jiaxun + */ +public class ConnectionException extends Exception { + + + +} diff --git a/group26/89460886/src/week03/source/download/api/ConnectionManager.java b/group26/89460886/src/week03/source/download/api/ConnectionManager.java new file mode 100644 index 0000000000..47bb30e9fb --- /dev/null +++ b/group26/89460886/src/week03/source/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package coding.coderising.download.api; + +/** + * @author jiaxun + */ +public interface ConnectionManager { + + Connection open(String url) throws ConnectionException; + +} diff --git a/group26/89460886/src/week03/source/download/api/DownloadListener.java b/group26/89460886/src/week03/source/download/api/DownloadListener.java new file mode 100644 index 0000000000..8202d6cbad --- /dev/null +++ b/group26/89460886/src/week03/source/download/api/DownloadListener.java @@ -0,0 +1,10 @@ +package coding.coderising.download.api; + +/** + * @author jiaxun + */ +public interface DownloadListener { + + void notifyFinished(); + +} diff --git a/group26/89460886/src/week03/source/download/impl/ConnectionImpl.java b/group26/89460886/src/week03/source/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..2cb3c342b3 --- /dev/null +++ b/group26/89460886/src/week03/source/download/impl/ConnectionImpl.java @@ -0,0 +1,43 @@ +package coding.coderising.download.impl; + +import coding.coderising.download.api.Connection; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +/** + * @author jiaxun + */ +public class ConnectionImpl implements Connection { + + private HttpURLConnection urlConnection; + + public ConnectionImpl(HttpURLConnection urlConnection) { + this.urlConnection = urlConnection; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream input = urlConnection.getInputStream(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + int length; + byte[] byteArray = new byte[1024]; + while ((length = input.read(byteArray)) != -1) { + output.write(byteArray, 0, length); + } + return output.toByteArray(); + } + + @Override + public int getContentLength() { + return urlConnection.getContentLength(); + } + + @Override + public void close() { + urlConnection.disconnect(); + } +} diff --git a/group26/89460886/src/week03/source/download/impl/ConnectionManagerImpl.java b/group26/89460886/src/week03/source/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..359a3c4d16 --- /dev/null +++ b/group26/89460886/src/week03/source/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,27 @@ +package coding.coderising.download.impl; + +import coding.coderising.download.api.Connection; +import coding.coderising.download.api.ConnectionException; +import coding.coderising.download.api.ConnectionManager; + +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * @author jiaxun + */ +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String urlString) throws ConnectionException { + + try { + URL url = new URL(urlString); + return new ConnectionImpl((HttpURLConnection) url.openConnection()); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/group26/89460886/src/week03/source/linkedlist/SinglyLinkedList.java b/group26/89460886/src/week03/source/linkedlist/SinglyLinkedList.java new file mode 100644 index 0000000000..a35cbfa944 --- /dev/null +++ b/group26/89460886/src/week03/source/linkedlist/SinglyLinkedList.java @@ -0,0 +1,357 @@ +package list; + +/** + * @author jiaxun + */ +public class SinglyLinkedList implements List { + + private Node head; + private int size; + + public SinglyLinkedList() { + size = 0; + } + + public void addFirst(Object data) { + Node node = new Node(data); + node.setNext(head); + head = node; + size++; + } + + public Node removeFirst() { + Node object = head; + head = object.getNext(); + size--; + return object; + } + + public Node removeLast() { + Node curr = head; + Node prev = null; + while (curr != null) { + prev = curr; + curr = curr.getNext(); + } + if (prev != null) { + prev.setNext(null); + } + size--; + return curr; + } + + public Node get(int index) { + if (index > size) { + throw new IndexOutOfBoundsException(); + } + Node curr = head; + while (curr != null) { + if (index == 0) + break; + curr = curr.getNext(); + index--; + + } + return curr; + } + + public Node remove(int index) { + Node curr = head; + Node prev = null; + while (curr != null) { + if (index == 0) + break; + prev = curr; + curr = curr.getNext(); + index--; + } + if (prev != null) { + prev.setNext(curr.getNext()); + curr.setNext(null); + } + size--; + return curr; + } + + public void addLast(Object object) { + if (head == null) { + head = new Node(object); + } else { + Node curr = head; + Node prev = null; + while (curr != null) { + prev = curr; + curr = curr.getNext(); + } + prev.setNext(new Node(object)); + } + size++; + } + + @Override + public void add(Object o) { + addLast(o); + } + + public void add(int index, Object object) { + Node curr = head; + Node prev = null; + while (curr != null) { + if (index == 0) + break; + prev = curr; + curr = curr.getNext(); + index--; + } + if (prev != null) { + Node newNode = new Node(object); + newNode.setNext(curr); + prev.setNext(newNode); + size++; + } + } + + public int size() { + return size; + } + + public Iterator iterator() { + return new SinglyLinkedListIterator(this); + } + + public void reverse() { + if (head == null || head.getNext() == null) return; + Node prev = null; + Node next = null; + Node curr = head; + while (curr != null) { + next = curr.getNext(); + curr.setNext(prev); + prev = curr; + curr = next; + } + head = prev; + } + + public void removeFirstHalf() { + if (head == null) return; + int half = size / 2; + Node curr = head; + while (half != 0) { + curr = curr.getNext(); + half--; + } + head = curr; + } + + public void remove(int i, int length) { + if (head == null || length == 0 || i >= size) return; + if (i + length >= size) length = size - i - 1; + Node prev = head; + Node curr = head; + int firstPos = i; + while (curr != null) { + if (firstPos == 0) + break; + prev = curr; + curr = curr.getNext(); + firstPos--; + } + int lastPos = length - i; + while (curr != null) { + if (lastPos == 0) + break; + curr = curr.getNext(); + lastPos--; + } + prev.setNext(curr == null ? null : curr.getNext()); + } + + public int[] getElements(SinglyLinkedList list) { + if (list == null || list.size() == 0) return null; + int[] resultList = new int[list.size()]; + int offset = 0; + int count = 0; + Node curr = head; + for (int i = 0, len = list.size(); i < len; i++) { + int index = (int) list.get(i).getData(); + index = index - offset; + offset = (int) list.get(i).getData(); + while (curr != null) { + if (index == 0) { + resultList[count++] = (int) curr.getData(); + break; + } + curr = curr.getNext(); + index--; + } + } + return resultList; + } + + public void subtract(SinglyLinkedList list) { + if (head == null || list == null) return; + Node curr = head; + Node prev = null; + int bCount = 0; + while (curr != null) { + if (bCount == list.size()) break; + int currData = (int) curr.getData(); + int bData = (int) list.get(bCount).getData(); + if (currData == bData) { + if (prev != null) { + prev.setNext(curr.getNext()); + } else { + head = curr.getNext(); + } + bCount++; + } else { + prev = curr; + } + curr = curr.getNext(); + } + } + + public void removeDuplicateValues() { + if (size <= 1) return; + Node prev = head; + Node curr = head.getNext(); + while (curr != null) { + if (prev.getData().equals(curr.getData())) { + if (curr.getNext() != null) { + curr = curr.getNext(); + } else { + curr = curr.getNext(); + prev.setNext(null); + } + } else { + prev.setNext(curr); + prev = curr; + curr = curr.getNext(); + } + } + } + + public void removeRange(int min, int max) { + if (head == null || (int) head.getData() > max) return; + Node prev = null; + Node next = null; + Node curr = head; + boolean lessHead = false; + if ((int) head.getData() > min) { + prev = head; + lessHead = true; + } + while (curr != null) { + int data = (int) curr.getData(); + if (!lessHead && data < min) { + prev = curr; + } + if (data > max) { + next = curr; + } + curr = curr.getNext(); + } + if (prev != null) { + if (prev == head && lessHead) { + head = next; + } else { + prev.setNext(next); + } + } + } + + public SinglyLinkedList intersection(SinglyLinkedList list) { + SinglyLinkedList resultList = new SinglyLinkedList(); + Node aCurr = head; + Node bCurr = list.head; + while (aCurr != null && bCurr != null) { + int a = (int) aCurr.getData(); + int b = (int) bCurr.getData(); + if (a < b) { + resultList.add(aCurr.getData()); + aCurr = aCurr.getNext(); + } else if (a > b) { + resultList.add(bCurr.getData()); + bCurr = bCurr.getNext(); + } else { + resultList.add(aCurr.getData()); + aCurr = aCurr.getNext(); + bCurr = bCurr.getNext(); + } + } + while (aCurr != null) { + resultList.add(aCurr.getData()); + aCurr = aCurr.getNext(); + } + while (bCurr != null) { + resultList.add(bCurr.getData()); + bCurr = bCurr.getNext(); + } + return resultList; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + Node current = head; + while (current != null) { + builder.append(current.toString()); + current = current.getNext(); + } + return builder.toString(); + } + + private class SinglyLinkedListIterator implements Iterator { + + private SinglyLinkedList linkedList; + private int currentPosition = 0; + + public SinglyLinkedListIterator(SinglyLinkedList linkedList) { + this.linkedList = linkedList; + } + + @Override + public boolean hasNext() { + return currentPosition < size; + } + + @Override + public Object next() { + return linkedList.get(currentPosition++); + } + + @Override + public Object remove() { + return linkedList.remove(--currentPosition); + } + } + + public static class Node { + + private Object data; + private Node next; + + public Node(Object data) { + this.data = data; + } + + public Object getData() { + return data; + } + + public Node getNext() { + return next; + } + + public void setNext(Node next) { + this.next = next; + } + + @Override + public String toString() { + return "[data is " + getData() + "]"; + } + } + +} diff --git a/group26/89460886/src/week03/test/TestDownload.java b/group26/89460886/src/week03/test/TestDownload.java new file mode 100644 index 0000000000..7bfcb8e589 --- /dev/null +++ b/group26/89460886/src/week03/test/TestDownload.java @@ -0,0 +1,57 @@ +package coding.coderising.download; + +import coding.coderising.download.api.ConnectionManager; +import coding.coderising.download.api.DownloadListener; +import coding.coderising.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @author jiaxun + */ +public class TestDownload { + + private static boolean downloaderFinished = false; + + @Before + public void setUp() { + + } + + @After + public void tearDown() { + + } + + @Test + public void testDownload() { + String downloadUrl = "http://img.ithome.com/newsuploadfiles/2017/3/20170324_152202_144.jpg"; + String savePath = "/Users/jiaxun/Downloads/download_thread.jpg"; + + FileDownloader downloader = new FileDownloader(downloadUrl, savePath); + + ConnectionManager connectionManager = new ConnectionManagerImpl(); + downloader.setConnectionManager(connectionManager); + + downloader.setDownloadListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloaderFinished = true; + } + }); + + downloader.execute(); + + while (!downloaderFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + } + +} diff --git a/group26/89460886/src/week03/test/TestSinglyLinkedList.java b/group26/89460886/src/week03/test/TestSinglyLinkedList.java new file mode 100644 index 0000000000..8ae36aed9a --- /dev/null +++ b/group26/89460886/src/week03/test/TestSinglyLinkedList.java @@ -0,0 +1,156 @@ +package list; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * @author jiaxun + */ +public class TestSinglyLinkedList { + + SinglyLinkedList singlyLinkedList; + + @Before + public void setUp() { + singlyLinkedList = new SinglyLinkedList(); + } + + @After + public void tearDown() { + + } + + @Test + public void testReverse() { + singlyLinkedList.add(3); + singlyLinkedList.add(7); + singlyLinkedList.add(10); + singlyLinkedList.reverse(); + int[] resultList = {10, 7, 3}; + for (int i = 0, len = resultList.length; i < len; i++) { + Assert.assertEquals(resultList[i], singlyLinkedList.get(i).getData()); + } + } + + @Test + public void testRemoveFirstHalf() { + singlyLinkedList.add(2); + singlyLinkedList.add(5); + singlyLinkedList.add(7); + singlyLinkedList.add(8); + singlyLinkedList.add(10); + singlyLinkedList.removeFirstHalf(); + int[] resultList = {7, 8, 10}; + for (int i = 0, len = resultList.length; i < len; i++) { + Assert.assertEquals(resultList[i], singlyLinkedList.get(i).getData()); + } + } + + @Test + public void testRemove() { + singlyLinkedList.add(1); + singlyLinkedList.add(2); + singlyLinkedList.add(3); + singlyLinkedList.add(4); + int[] resultList = {1, 3, 4}; + singlyLinkedList.remove(1, 1); + for (int i = 0, len = resultList.length; i < len; i++) { + Assert.assertEquals(singlyLinkedList.get(i).getData(), resultList[i]); + } + } + + @Test + public void testGetElements() { + singlyLinkedList.add(11); + singlyLinkedList.add(101); + singlyLinkedList.add(201); + singlyLinkedList.add(301); + singlyLinkedList.add(401); + singlyLinkedList.add(501); + singlyLinkedList.add(601); + singlyLinkedList.add(701); + SinglyLinkedList listB = new SinglyLinkedList(); + listB.add(1); + listB.add(3); + listB.add(4); + listB.add(6); + int[] expectedArray = {101, 301, 401, 601}; + int[] resultArray = singlyLinkedList.getElements(listB); + for (int i = 0, len = expectedArray.length; i < len; i++) { + Assert.assertEquals(expectedArray[i], resultArray[i]); + } + } + + @Test + public void testSubtract() { + singlyLinkedList.add(11); + singlyLinkedList.add(101); + singlyLinkedList.add(201); + singlyLinkedList.add(301); + singlyLinkedList.add(401); + singlyLinkedList.add(501); + singlyLinkedList.add(601); + singlyLinkedList.add(701); + SinglyLinkedList listB = new SinglyLinkedList(); + listB.add(101); + listB.add(301); + listB.add(401); + listB.add(601); + singlyLinkedList.subtract(listB); + int[] expectedArray = {11, 201, 501, 701}; + for (int i = 0, len = expectedArray.length; i < len; i++) { + Assert.assertEquals(expectedArray[i], singlyLinkedList.get(i).getData()); + } + } + + @Test + public void testRemoveDuplicateValues() { + singlyLinkedList.add(11); + singlyLinkedList.add(101); + singlyLinkedList.add(201); + singlyLinkedList.add(201); + singlyLinkedList.add(301); + singlyLinkedList.add(301); + singlyLinkedList.add(301); + singlyLinkedList.removeDuplicateValues(); + int[] expectedArray = {11, 101, 201, 301}; + for (int i = 0, len = expectedArray.length; i < len; i++) { + Assert.assertEquals(expectedArray[i], singlyLinkedList.get(i).getData()); + } + } + + @Test + public void testRemoveRange() { + singlyLinkedList.add(11); + singlyLinkedList.add(101); + singlyLinkedList.add(201); + singlyLinkedList.add(301); + singlyLinkedList.add(401); + singlyLinkedList.removeRange(10, 400); + int[] expectedArray = {401}; + for (int i = 0, len = expectedArray.length; i < len; i++) { + Assert.assertEquals(expectedArray[i], singlyLinkedList.get(i).getData()); + } + } + + @Test + public void testIntersection() { + singlyLinkedList.add(12); + singlyLinkedList.add(18); + singlyLinkedList.add(32); + singlyLinkedList.add(98); + SinglyLinkedList bList = new SinglyLinkedList(); + bList.add(34); + bList.add(51); + bList.add(53); + bList.add(78); + SinglyLinkedList resultList = singlyLinkedList.intersection(bList); + int[] expectedArray = {12, 18, 32, 34, 51, 53, 78, 98}; + for (int i = 0, len = expectedArray.length; i < len; i++) { + Assert.assertEquals(expectedArray[i], resultList.get(i).getData()); + } + } + +} diff --git a/group26/89460886/src/week04/source/LRUPageFrame.java b/group26/89460886/src/week04/source/LRUPageFrame.java new file mode 100644 index 0000000000..44b7ad7a45 --- /dev/null +++ b/group26/89460886/src/week04/source/LRUPageFrame.java @@ -0,0 +1,159 @@ +package list; + +/** + * @author jiaxun + */ +public class LRUPageFrame { + + private int capacity; + private Node first; + private Node last; + private int size = 0; + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + public void access(int pageNum) { + if (size < capacity) { + addFirst(pageNum); + } else { + Node node = searchNode(pageNum); + if (node == null) { + removeLast(); + addFirst(pageNum); + } else { + if (node.getData() == first.getData()) return; + if (node.getData() == last.getData()) { + last = node.getPrev(); + node.getPrev().setNext(null); + node.setPrev(null); + node.setNext(first); + first.setPrev(node); + first = node; + } else { + node.getPrev().setNext(node.getNext()); + node.getNext().setPrev(node.getPrev()); + node.setNext(first); + node.setPrev(null); + first = node; + } + } + } + } + + public Node searchNode(int pageNum) { + Node curr = first; + while (curr != null) { + if (curr.getData() == pageNum) { + return curr; + } + curr = curr.getNext(); + } + return null; + } + + public void addFirst(int data) { + Node node = new Node(data); + if (first == null) { + first = node; + } else if (last == null) { + last = first; + first = node; + first.setNext(last); + last.setPrev(first); + } else { + node.setNext(first); + first.setPrev(node); + first = node; + } + size++; + } + + public void addLast(int data) { + Node node = new Node(data); + if (first == null) { + first = node; + } else if (last == null) { + last = node; + first.setNext(last); + last.setPrev(first); + } else { + node.setPrev(last); + last.setNext(node); + last = node; + } + size++; + } + + public void removeLast() { + if (last != null && last.getPrev() != null) { + Node prev = last.getPrev(); + last.getPrev().setNext(null); + last = prev.getData() == first.getData() ? null : last.getPrev(); + } else if (first != null) { + first = null; + } + if (size > 0) { + size--; + } + } + + public int size() { + return size; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + Node curr = first; + while (curr != null) { + builder.append(curr.getData()); + if (curr.getNext() != null) { + builder.append(","); + } + curr = curr.getNext(); + } + return builder.toString(); + } + + private static class Node { + + private int data; + private Node prev; + private Node next; + + public Node(int data) { + this.data = data; + } + + public int getData() { + return data; + } + + public void setData(int data) { + this.data = data; + } + + public Node getPrev() { + return prev; + } + + public void setPrev(Node prev) { + this.prev = prev; + } + + public Node getNext() { + return next; + } + + public void setNext(Node next) { + this.next = next; + } + + @Override + public String toString() { + return "[data is " + data + "]"; + } + } +} diff --git a/group26/89460886/src/week04/test/TestLRUPageFrame.java b/group26/89460886/src/week04/test/TestLRUPageFrame.java new file mode 100644 index 0000000000..a82a2512ac --- /dev/null +++ b/group26/89460886/src/week04/test/TestLRUPageFrame.java @@ -0,0 +1,32 @@ +package list; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author jiaxun + */ +public class TestLRUPageFrame { + + @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/group26/lizhy2017/homework/second/array/ArrayUtil.java b/group26/lizhy2017/homework/second/array/ArrayUtil.java index 253356ef7d..1e7855bd1b 100644 --- a/group26/lizhy2017/homework/second/array/ArrayUtil.java +++ b/group26/lizhy2017/homework/second/array/ArrayUtil.java @@ -9,14 +9,14 @@ public class ArrayUtil { * 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] * 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] * - * @param origin + * @param origin 整形数组 */ - public void reverseArray(int[] origin) { - if (null != origin) return; - for (int i = 0; i < origin.length; i++) { + public static void reverseArray(int[] origin) { + if (null == origin) return; + for (int i = 0; i < origin.length / 2; i++) { int temp = origin[i]; origin[i] = origin[origin.length - i - 1]; - origin[i] = temp; + origin[origin.length - i - 1] = temp; } } @@ -29,16 +29,18 @@ public void reverseArray(int[] origin) { * @return */ - public int[] removeZero(int[] oldArray) { - if (null != oldArray) { - return null; - } + public static int[] removeZero(int[] oldArray) { + if (null == oldArray) return null; + int size = oldArray.length; for (int i = 0; i < oldArray.length; i++) { if (oldArray[i] == 0) { System.arraycopy(oldArray, i + 1, oldArray, i, oldArray.length - i - 1); + size--; } } - return oldArray; + int[] newArray = new int[size]; + System.arraycopy(oldArray, 0, newArray, 0, size); + return newArray; } /** @@ -50,30 +52,34 @@ public int[] removeZero(int[] oldArray) { * @return */ - public int[] merge(int[] array1, int[] array2) { - if (null != array1 && null != array2) return null; + public static int[] merge(int[] array1, int[] array2) { + if (null == array1 || null == array2) return null; int[] temp = new int[array1.length + array2.length]; int i = 0, j = 0; if (array1.length >= array2.length) { while (i < array2.length) { - i++; if (array1[i] <= array2[i]) temp[i] = array1[i]; else temp[i] = array2[i]; + i++; } - System.arraycopy(array1, i + 1, temp, i + 1, temp.length - i - 1); + System.arraycopy(array1, i - 1, temp, 2 * i - 1, temp.length - 2 * i - 1); } else { - while (j < array1.length) { - j++; - if (array1[j] <= array2[j]) + while (j < array1.length - 1) { + if (array1[j] <= array2[j]) { temp[j] = array1[j]; - else + if (array1[j + 1] > array2[j]) { + temp[j] = array2[j]; + } + } else temp[j] = array2[j]; + j++; + } - System.arraycopy(array1, j + 1, temp, j + 1, temp.length - j - 1); + System.arraycopy(array2, j - 1, temp, 2 * j - 1, temp.length - 2 * j - 1); } - return null; + return temp; } /** @@ -86,7 +92,7 @@ public int[] merge(int[] array1, int[] array2) { * @param size * @return */ - public int[] grow(int[] oldArray, int size) { + public static int[] grow(int[] oldArray, int size) { int oldCapacity = oldArray.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity < size) { @@ -106,7 +112,7 @@ public int[] grow(int[] oldArray, int size) { * @param max * @return */ - public int[] fibonacci(int max) { + public static int[] fibonacci(int max) { if (max <= 1) return new int[0]; int[] temp = new int[max]; @@ -131,7 +137,7 @@ public int[] fibonacci(int max) { * @param max * @return */ -// public int[] getPrimes(int max) { +// public static int[] getPrimes(int max) { // int[] temp = new int[max]; // if (max < 2) // return new int[0]; @@ -165,7 +171,7 @@ public int[] fibonacci(int max) { * @param max * @return */ - public int[] getPerfectNumbers(int max) { + public static int[] getPerfectNumbers(int max) { int[] temp = new int[max]; int index = 0; for (int i = 1; i <= max; i++) { @@ -192,7 +198,7 @@ public int[] getPerfectNumbers(int max) { * @param seperator * @return */ - public String join(int[] array, String seperator) { + public static String join(int[] array, String seperator) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < array.length; i++) { if (i == array.length - 1) { diff --git a/group26/lizhy2017/homework/second/array/ArrayUtilTest.java b/group26/lizhy2017/homework/second/array/ArrayUtilTest.java new file mode 100644 index 0000000000..58827657da --- /dev/null +++ b/group26/lizhy2017/homework/second/array/ArrayUtilTest.java @@ -0,0 +1,90 @@ +package second.array; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * ${} + * Created by spark_lizhy on 2017/3/20. + */ + +public class ArrayUtilTest { + + private int[] temp; + private int size; + + @Before + public void setUp() throws Exception { + size = 10; + temp = new int[size]; + for (int i = 0; i < size; i++) { + temp[i] = i; + } + + } + + @Test + public void reverseArray() throws Exception { + ArrayUtil.reverseArray(temp); + for (int i = 0; i < size; i++) { + Assert.assertEquals(size - 1 - i, temp[i]); + } + } + + @Test + public void removeZero() throws Exception { + for (int i = 0; i < size; i++) { + if (i % 5 == 0) { + temp[i] = 0; + } else { + temp[i] = i; + } + } + + temp = ArrayUtil.removeZero(temp); + Assert.assertNotNull(temp); + for (int i = 0; i < temp.length; i++) { + if (temp[i] != 0) { + continue; + } + Assert.assertEquals(temp[i], i); + } + + // 测试空数组 + { + int[] testArray = new int[5]; + for (int i = 0; i < 5; i++) { + testArray[i] = 0; + } + + int[] newArray = ArrayUtil.removeZero(testArray); + Assert.assertNotNull(newArray); + Assert.assertEquals(newArray.length, 0); + } + } + + @Test + public void merge() throws Exception { + // 构建数组 + int[] array1 = new int[10]; + int[] array2 = new int[11]; + array2[10] = 100; + for (int i = 0; i < 10; i++) { + if (i % 2 == 0) { + array1[i / 2] = i; // 0, 2, 4, 6, 8 + } else { + array2[i / 2] = i; // 1, 3, 5, 7, 9 + } + } + + // 测试merge + { + int[] merge = ArrayUtil.merge(array1, array2); + Assert.assertNotNull(merge); + Assert.assertEquals(merge.length, 21); + } + + } + +} diff --git a/group26/lizhy2017/homework/third/basic/LRUPageFameTest.java b/group26/lizhy2017/homework/third/basic/LRUPageFameTest.java new file mode 100644 index 0000000000..32bf061852 --- /dev/null +++ b/group26/lizhy2017/homework/third/basic/LRUPageFameTest.java @@ -0,0 +1,32 @@ +package third.basic; + +import org.junit.Assert; +import org.junit.Test; + +/** + * ${} + * Created by spark_lizhy on 2017/3/31. + */ + +public class LRUPageFameTest { + @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/group26/lizhy2017/homework/third/basic/LRUPageFrame.java b/group26/lizhy2017/homework/third/basic/LRUPageFrame.java new file mode 100644 index 0000000000..29fa687bba --- /dev/null +++ b/group26/lizhy2017/homework/third/basic/LRUPageFrame.java @@ -0,0 +1,63 @@ +package third.basic; + +/** + * ${} + * Created by spark_lizhy on 2017/3/31. + */ +/** + * 用双向链表实现 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; + + } + + /** + * 获取缓存中对象 + * + * @return + */ + public void access(int pageNum) { + + + } + + + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group26/lizhy2017/homework/third/basic/LinkedList.java b/group26/lizhy2017/homework/third/basic/LinkedList.java new file mode 100644 index 0000000000..49265f7b31 --- /dev/null +++ b/group26/lizhy2017/homework/third/basic/LinkedList.java @@ -0,0 +1,204 @@ +package third.basic; + +import java.util.Objects; + +/** + * ${} + * Created by spark_lizhy on 2017/3/31. + */ + +public class LinkedList { + private Node mHead; + private Node mCurrent; + private int mSize = 0; + + public void add(T o) { + addLast(o); + mSize++; + + } + + public void add(int index, T o) { + checkIndex(index); + + Node next = find(index); + Node pre = next.previous; + Node current = new Node<>(o, next, pre); + next.previous = current; + pre.next = current; + mSize++; + + } + + private Node find(int index) { + Node tra = mHead; + if (index < (mSize >> 1)) { + for (int i = 0; i <= index; i++) { + tra = tra.next; + } + } else { + for (int i = mSize; i > index; i--) { + tra = tra.previous; + } + } + return tra; + } + + private void checkIndex(int index) { + if (index >= mSize || index < 0) { + throw new IndexOutOfBoundsException("Index:" + index + " Size:" + mSize); + } + } + + public Object get(int index) { + checkIndex(index); + + return find(index).data; + } + + public T remove(int index) { + checkIndex(index); + //重链接 + Node temp = this.find(index); + Node next = temp.next; + Node pre = temp.previous; + pre.next = next; + next.previous = pre; + //清除数据 + T removedObject = temp.data; + temp.data = null; + temp.next = null; + temp.previous = null; + mSize--; + return removedObject; + } + + public int size() { + return mSize; + } + + public void addFirst(T o) { + Node next = mHead.next; + Node first = new Node<>(o, next, mHead); + next.next = first; + next.previous = first; + mSize++; + + } + + public void addLast(T o) { + Node last = mHead.previous; + Node temp = new Node<>(o, mHead, last); + mHead.previous = temp; + last.next = temp; + mSize++; + } + + public T removeFirst() { + return remove(0); + } + + public T removeLast() { + return remove(mSize - 1); + } + + + /** + * 把该链表逆置 + * 例如链表为 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; + } + + + private static class Node { + T data; + Node next; + Node previous; + + public Node(T data) { + this.data = data; + this.next = this; + this.previous = this; + } + + public Node(T data, Node next, Node previous) { + this.data = data; + this.next = next; + this.previous = previous; + } + } +} diff --git a/group26/lizhy2017/homework/third/download/DownloadThread.java b/group26/lizhy2017/homework/third/download/DownloadThread.java new file mode 100644 index 0000000000..9fa8cb2659 --- /dev/null +++ b/group26/lizhy2017/homework/third/download/DownloadThread.java @@ -0,0 +1,51 @@ +package third.download; + + +import java.io.IOException; +import java.io.RandomAccessFile; + +import third.download.api.Connection; +import third.download.api.ConnectionException; +import third.download.api.DownloadListener; + +public class DownloadThread extends Thread { + + private RandomAccessFile accessFile; + private DownloadListener listener; + private Connection conn; + private int startPos; + private int endPos; + + public DownloadThread(Connection conn, int startPos, int endPos, DownloadListener listener) { + this.listener = listener; + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + + } + + public void run() { + try { + byte[] bytes = conn.read(startPos, endPos); + accessFile = new RandomAccessFile("./" + conn.getFileName(), "rw"); + accessFile.seek(startPos); + accessFile.write(bytes); + } catch (IOException e) { + e.printStackTrace(); + } catch (ConnectionException e) { + e.printStackTrace(); + } finally { + if (null != accessFile) + try { + accessFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (null != conn) + conn.close(); + if (null != listener) + listener.notifyFinished(); + } + } +} diff --git a/group26/lizhy2017/homework/third/download/FileDownloader.java b/group26/lizhy2017/homework/third/download/FileDownloader.java new file mode 100644 index 0000000000..498b09ee97 --- /dev/null +++ b/group26/lizhy2017/homework/third/download/FileDownloader.java @@ -0,0 +1,86 @@ +package third.download; + +import java.util.concurrent.atomic.AtomicInteger; + +import third.download.api.Connection; +import third.download.api.ConnectionException; +import third.download.api.ConnectionManager; +import third.download.api.DownloadListener; + + +public class FileDownloader { + private final static int THREAD_NUM=15; + private String url; + private DownloadListener listener; + private ConnectionManager cm; + private AtomicInteger atomicInteger=new AtomicInteger(); + + 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 { + int length = cm.getContentLength(url); + int perTread_lenth=length/THREAD_NUM; + int redundant=length%THREAD_NUM; + 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/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 clzPaths = new ArrayList(); + /* + public byte[] readBinaryCode(String className) { + className = className.replace('.', File.separatorChar); + + for(String path:this.clzPaths) + { + String clzFileName = path + File.separatorChar+className; + byte[] codes = loadClassFile_V2(clzFileName); + if(codes != null){ + return codes; + } + + } + + return null; + + + } + + private byte[] loadClassFile_V2(String clzFileName) { + File f= new File(clzFileName); + try { + return IOUtils.toByteArray(new FileInputStream(f)); + + } catch (Exception e) { + + return null; + } + + } + + //第一种加载类的方法 + private byte[] loadClassFile_V1(String clzFileName) { + /*BufferedInputStream bis = null; + try{ + File f = new File(clzFileName); + bis = new BufferedInputStream(new FileInputStream(f)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length = -1; + while((length = bis.read(buffer))!=-1) + { + bos.write(buffer,0,length); + + } + byte[] codes = bos.toByteArray(); + return codes; + }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() { + int count = 0; + String clzP = null; + for(String clzPathName:clzPaths){ + if(count=capacity){ + removeLast(); + } + addNewNodeAtHead(node); + + } + + } + + + + private void moveExistingNodeToHead(Node node) { + if(first.pageNum == node.pageNum ){ + return; + }else if(last.pageNum == node.pageNum) { + Node lastToHead = last; + last = last.prev; + last.next = null; + lastToHead.prev = null; + lastToHead.next = first; + first.prev = lastToHead; + first = lastToHead; + + + + }else { + Node MiddleNode = first.next; + first.next = last; + last.prev = first; + MiddleNode.next = first; + MiddleNode.prev = null; + first.prev = MiddleNode; + first = MiddleNode; + + + } + + } + + private void addNewNodeAtHead(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; + + + } + curreantSize++; + + + } + + private boolean isEmpty() { + // TODO Auto-generated method stub + return (curreantSize==0); + } + + private void removeLast() { + Node prev = last.prev; + prev.next = null; + last.prev = null; + last = prev ; + this.curreantSize--; + + } + + private Node find(int pageNum) { + Node node = first; + while(node!=null){ + if(node.pageNum==pageNum){ + return node; + } + node = node.next; + + + } + 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/group27/1016908591/week04/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group27/1016908591/week04/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group27/1016908591/week04/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/group27/1252327158/task1_20170312/src/com/coding/ArrayListTest.java b/group27/1252327158/task1_20170312/src/com/coding/ArrayListTest.java index a96d7287fb..4370a34a3d 100644 --- a/group27/1252327158/task1_20170312/src/com/coding/ArrayListTest.java +++ b/group27/1252327158/task1_20170312/src/com/coding/ArrayListTest.java @@ -9,7 +9,7 @@ import org.junit.Test; public class ArrayListTest { - + ArrayList 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..e5068a4e44 --- /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..7ede4cbb34 --- /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..c9c7b05c7d --- /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..0957eaf7f4 --- /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..1551a80b3d --- /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..ce045393b1 --- /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..bf9807b307 --- /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..26477be3eb --- /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..18836b4a28 --- /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/coderising/jvm/loader/ClassFileLoader.java b/group27/383117348/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..a1eb5cc155 --- /dev/null +++ b/group27/383117348/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,77 @@ +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; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + className = className.replace(".", "\\"); + File file = null; + for(String classPath : clzPaths){ + file = new File(classPath + "\\" + className + ".class"); + if(file.exists()){ + break; + } + } + if(!file.exists()){ + try { + throw new ClassNotFoundException(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); + BufferedInputStream in = null; + try { + in = new BufferedInputStream(new FileInputStream(file)); + int buf_size = 1024; + byte[] buffer = new byte[buf_size]; + int len = 0; + while (-1 != (len = in.read(buffer, 0, buf_size))) { + bos.write(buffer, 0, len); + } + return bos.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + bos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return null; + } + + public void addClassPath(String path) { + if (path != null && path.length() > 0) { + if (!clzPaths.contains(path)) { + clzPaths.add(path); + } + } + } + + public String getClassPath() { + String paths = ""; + for (String s : clzPaths) { + paths += s + ";"; + } + paths = paths.substring(0, paths.length() - 1); + return paths; + } + +} diff --git a/group27/383117348/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group27/383117348/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..2ac63afcd9 --- /dev/null +++ b/group27/383117348/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,76 @@ +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 = "E:\\MyGit\\coding2017\\group27\\383117348\\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(); + System.out.println(clzPath); + 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/group27/383117348/src/com/coderising/jvm/test/EmployeeV1.java b/group27/383117348/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..67735a92b0 --- /dev/null +++ b/group27/383117348/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/group27/383117348/src/com/coding/basic/Queue.java b/group27/383117348/src/com/coding/basic/Queue.java index 84cb43e3db..4bd32c067b 100644 --- a/group27/383117348/src/com/coding/basic/Queue.java +++ b/group27/383117348/src/com/coding/basic/Queue.java @@ -2,6 +2,8 @@ import org.junit.Test; +import com.coding.basic.linklist.LinkedList; + public class Queue { private int size = 0; private LinkedList linkedList = new LinkedList(); diff --git a/group27/383117348/src/com/coding/basic/linklist/LRUPageFrame.java b/group27/383117348/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..b50f3df5e8 --- /dev/null +++ b/group27/383117348/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,139 @@ +package com.coding.basic.linklist; + + +/** + * 用双向链表实现LRU算法 + * + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + } + /** + * LRU算法: + */ + 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) { + Node node = checkExist(pageNum); + //如果这个页面在缓存中存在 + if (node != null) { + // 将当前节点移动至第一个 + moveTofirst(node); + } else { + //不存在后比较当前是否已经满队列了 + if (size < capacity) { + //如果还有空闲队列 + // 添加一个节点在栈顶 + final Node n = first; + final Node firstNode = new Node(); + firstNode.next = n; + firstNode.pageNum = pageNum; + firstNode.prev = null; + this.first = firstNode; + if (n == null) { + last = firstNode; + } else { + n.prev = firstNode; + } + size++; + } else { + //否则,添加一个节点在栈顶,栈底的节点移除 + addNode(pageNum); + } + } + } + //如果超出了缓存范围,则添加到栈顶,栈底的节点移除 + private void addNode(int pageNum) { + Node node = new Node(); + node.pageNum = pageNum; + node.next = first; + first.prev = node; + first = node; + last = last.prev; + last.next = null; + } + /** + * 如果在队列中存在,则移动至首位 + * @param node + */ + private void moveTofirst(Node node) { + if(node==first){ + return; + } + if(node==last){ + first.prev = node; + node.next = first; + first = node; + last = node.prev; + last.next = null; + first.prev = null; + + }else{ + node.prev.next = node.next; + node.next.prev = node.prev; + node.prev = null; + node.next = first; + first.prev = node; + first = node; + } + + } + + /** + * 检查是否在队列中存在页数 + * @param pageNum + * @return + */ + private Node checkExist(int pageNum) { + Node node = first; + for(int i=0;i size) { - throw new IndexOutOfBoundsException("链表下标越界"); - } - } - - /** - * 迭代器内部类 - * - * @author Adminstater - * - */ - private class Iter implements Iterator { - private int nextIndex = 0; - - @Override - public boolean hasNext() { - // TODO Auto-generated method stub - return nextIndex != size; - } - - @Override - public Object next() { - // TODO Auto-generated method stub - int i = nextIndex++; - if (i > size - 1) - throw new IndexOutOfBoundsException(); - return getNodeByIndex(i).data; - } - - } - - /** - * 节点内部类 - * - * @author Adminstater - * - */ - private static class Node { - Object data; - Node next; - Node prev; - - private Node(Object data, Node next, Node prev) { - this.data = data; - this.next = next; - this.prev = prev; - } - - private Node() { - - } - } - - /*------------------------------------------------------单元测试----------------------------------------------------*/ - - /** - * 测试添加方法功能 - */ - // add(Object o) - @Test - public void TestAddFunction() { - - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - System.out.println("添加完毕"); - - } - - // add(int index,Object o) - @Test - public void TestAddIndexFunction() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - for (int x = 0; x < list.size(); x++) { - System.out.println(list.get(x)); - } - list.add(3, 111); - System.out.println(list.get(3)); - } - - // addFirst(Object o) - @Test - public void TestAddFirstFunction() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - System.out.println(list.get(0)); - list.addFirst(20); - System.out.println(list.get(0)); - } - - // addLast(Object o) - @Test - public void TestAddLastFunction() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - System.out.println(list.get(list.size() - 1)); - list.addLast(111); - System.out.println(list.get(list.size() - 1)); - } - - /** - * remove方法测试 - */ - // removeFirst() - @Test - public void TestRemoveFirst() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - System.out.println(list.get(0)); - list.removeFirst(); - System.out.println(list.get(0)); - } - - // removeLast() - @Test - public void TestRemoveLast() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - System.out.println(list.get(list.size() - 1)); - list.removeLast(); - System.out.println(list.get(list.size() - 1)); - } - - // remove(int index) - @Test - public void TestRemoveFunction() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - System.out.println(list.get(50)); - list.remove(50); - System.out.println(list.get(50)); - } - - /** - * Iterator测试 - */ - @Test - public void TestIterator() { - LinkedList list = new LinkedList(); - for (int i = 0; i < 100; i++) { - list.add(i); - } - Iterator ite = list.iterator(); - while (ite.hasNext()) { - System.out.println(ite.next()); - } - } - - public static void main(String[] args) { - java.util.LinkedList list = null; - } -} +package com.coding.basic.linklist; + +import java.util.Arrays; +import java.util.NoSuchElementException; + +import org.junit.Test; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +public class LinkedList implements List { + + private Node first; + + private Node last; + + private int size; + + /** + * 头部添加节点方法 + */ + private void linkFirst(Object o) { + final Node node = first; + final Node firstNode = new Node(o, node, null); + this.first = firstNode; + if (node == null) { + last = firstNode; + } else { + node.prev = firstNode; + } + size++; + } + + /** + * 末端添加节点方法 + * + * @param o + */ + private void linkLast(Object o) { + final Node node = last; + final Node lastNode = new Node(o, null, node); + last = lastNode; + if (node == null) { + first = lastNode; + } else { + node.next = lastNode; + } + size++; + } + + /** + * 在链表末端添加节点 + */ + public void add(Object o) { + if (o != null) + linkLast(o); + } + + /** + * 在指定下标处添加节点 + */ + public void add(int index, Object o) { + checkIndex(index); + Node befo = getNodeByIndex(index); + linkBefore(o, befo); + } + + /** + * 根据下标获取节点 + */ + public Object get(int index) { + checkIndex(index); + return getNodeByIndex(index).data; + } + + /** + * 根据下标移除节点 + */ + public Object remove(int index) { + checkIndex(index); + Node element = first; + if (index == 0) { + first = first.next; + } else { + Node pos = first; + for (int i = 0; i < index - 1; i++) { + pos = pos.next; + } + element = pos.next; + pos.next = pos.next.next; + } + size--; + return element.data; + } + + /** + * 返回链表长度 + */ + public int size() { + return size; + } + + /** + * 在链表头添加节点 + * + * @param o + */ + public void addFirst(Object o) { + linkFirst(o); + } + + /** + * 在链表最后添加节点 + * + * @param o + */ + public void addLast(Object o) { + linkLast(o); + } + + /** + * 移除链表首个元素 + * + * @return + */ + public Object removeFirst() { + Node node = first; + if (node == null) + throw new NoSuchElementException(); + else { + Node next = node.next; + if (next == null) + first = null; + else { + first = next; + first.prev = null; + } + } + size--; + return node.data; + } + + /** + * 移除链表最后一个元素 + * + * @return + */ + public Object removeLast() { + Node node = last; + if (last == null) + throw new NoSuchElementException(); + else { + Node prev = node.prev; + if (prev == null) + last = null; + else { + last = prev; + last.next = null; + } + } + size--; + return node.data; + } + + /** + * 迭代方法 + * + * @return + */ + public Iterator iterator() { + return new Iter(); + } + + /** + * 在节点之前插入一个新的节点 + * + * @param data + * @param befo + */ + private void linkBefore(Object data, Node befo) { + final Node prev = befo.prev; + final Node node = new Node(data, befo, prev); + befo.prev = node; + if (prev == null) + first = node; + else + prev.next = node; + size++; + } + + /** + * 根据下标获取节点 + * + * @param index + * @return + */ + private Node getNodeByIndex(int index) { + checkIndex(index); + + Node node = first; + for (int x = 0; x < index; x++) { + node = node.next; + } + return node; + } + + /** + * 检查下标是否越界 + * + * @param index + */ + private void checkIndex(int index) { + // TODO Auto-generated method stub + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("链表下标越界"); + } + } + + /** + * 迭代器内部类 + * + * @author Adminstater + * + */ + private class Iter implements Iterator { + private int nextIndex = 0; + + @Override + public boolean hasNext() { + // TODO Auto-generated method stub + return nextIndex != size; + } + + @Override + public Object next() { + // TODO Auto-generated method stub + int i = nextIndex++; + if (i > size - 1) + throw new IndexOutOfBoundsException(); + return getNodeByIndex(i).data; + } + + } + + /** + * 节点内部类 + * + * @author Adminstater + * + */ + private static class Node { + Object data; + Node next; + Node prev; + + private Node(Object data, Node next, Node prev) { + this.data = data; + this.next = next; + this.prev = prev; + } + + private Node() { + + } + } + + /** + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse() { + if (size == 0) + return; + + for (int i = 1; i < size; i++) { + addFirst(get(i)); + remove(i + 1); + } + + } + + @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.print("----"); + System.out.print(it.next() + " "); + } + } + + /** + * 删除一个单链表的前半部分 例如:list = 2->5->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 < removeNum; i++) { + removeFirst(); + } + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * + * @param i + * @param length + */ + public void remove(int i, int length) { + if (length + 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) { + 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)); + } + + 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(); + for (int i = 0; i < size; i++) { + for (int j = 0; j < list.size; j++) { + if (get(i).equals(list.get(j))) { + newList.add(list.get(j)); + break; + } + } + } + return newList; + } + + /*------------------------------------------------------单元测试----------------------------------------------------*/ + + /** + * 测试添加方法功能 + */ + // add(Object o) + @Test + public void TestAddFunction() { + + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + System.out.println("添加完毕"); + + } + + // add(int index,Object o) + @Test + public void TestAddIndexFunction() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + for (int x = 0; x < list.size(); x++) { + System.out.println(list.get(x)); + } + list.add(3, 111); + System.out.println(list.get(3)); + } + + // addFirst(Object o) + @Test + public void TestAddFirstFunction() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + System.out.println(list.get(0)); + list.addFirst(20); + System.out.println(list.get(0)); + } + + // addLast(Object o) + @Test + public void TestAddLastFunction() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + System.out.println(list.get(list.size() - 1)); + list.addLast(111); + System.out.println(list.get(list.size() - 1)); + } + + /** + * remove方法测试 + */ + // removeFirst() + @Test + public void TestRemoveFirst() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + System.out.println(list.get(0)); + list.removeFirst(); + System.out.println(list.get(0)); + } + + // removeLast() + @Test + public void TestRemoveLast() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + System.out.println(list.get(list.size() - 1)); + list.removeLast(); + System.out.println(list.get(list.size() - 1)); + } + + // remove(int index) + @Test + public void TestRemoveFunction() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + System.out.println(list.get(50)); + list.remove(50); + System.out.println(list.get(50)); + } + + /** + * Iterator测试 + */ + @Test + public void TestIterator() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 100; i++) { + list.add(i); + } + Iterator ite = list.iterator(); + while (ite.hasNext()) { + System.out.println(ite.next()); + } + } + + private LinkedList getList() { + LinkedList list = new LinkedList(); + for (int i = 0; i < 10; i++) { + list.add(i); + } + return list; + } +} diff --git a/group27/513274874/data-structure/down.jpg b/group27/513274874/data-structure/down.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d7fccb49d254800f2d6c17911498e8523b68b0d7 GIT binary patch literal 14104 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 literal 0 HcmV?d00001 diff --git a/group27/513274874/data-structure/src/com/coderising/download/DownloadThread.java b/group27/513274874/data-structure/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..605f1ba10c --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,30 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; + +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread{ + + Connection conn; + 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(){ + try { + byte[] buff = conn.read(startPos,endPos); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/group27/513274874/data-structure/src/com/coderising/download/FileDownloader.java b/group27/513274874/data-structure/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..347c6bc93c --- /dev/null +++ b/group27/513274874/data-structure/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.DownloadListener; +import com.coderising.download.api.ConnectionManager; + + +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/group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java b/group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..85aeeff9fc --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.coderising.download; + +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.ConnectionManager; + +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/group27/513274874/data-structure/src/com/coderising/download/api/Connection.java b/group27/513274874/data-structure/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group27/513274874/data-structure/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/513274874/data-structure/src/com/coderising/download/api/ConnectionException.java b/group27/513274874/data-structure/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1551a80b3d --- /dev/null +++ b/group27/513274874/data-structure/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/513274874/data-structure/src/com/coderising/download/api/ConnectionManager.java b/group27/513274874/data-structure/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group27/513274874/data-structure/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/513274874/data-structure/src/com/coderising/download/api/DownloadListener.java b/group27/513274874/data-structure/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group27/513274874/data-structure/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/513274874/data-structure/src/com/coderising/download/demo/DownThread.java b/group27/513274874/data-structure/src/com/coderising/download/demo/DownThread.java new file mode 100644 index 0000000000..18b21da57c --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/download/demo/DownThread.java @@ -0,0 +1,72 @@ +package com.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/data-structure/src/com/coderising/download/demo/MutilDown.java b/group27/513274874/data-structure/src/com/coderising/download/demo/MutilDown.java new file mode 100644 index 0000000000..6358700d4f --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/download/demo/MutilDown.java @@ -0,0 +1,72 @@ +package com.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/data-structure/src/com/coderising/download/impl/ConnectionImpl.java b/group27/513274874/data-structure/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..01ef73bfa5 --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,100 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.Connection; + +import java.io.*; +import java.net.URL; +import java.net.URLConnection; + +public class ConnectionImpl implements Connection { + private URL url; + + // 定义字节数组(取水的竹筒)的长度 + private final int BUFF_LEN = 32; + + // 下载资源对应的输入流 + private InputStream is; + + + 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/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group27/513274874/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..f9bbeb5a4f --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,29 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.Connection; +import com.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 { + + 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/513274874/data-structure/src/com/coderising/litestruts/LoginAction.java b/group27/513274874/data-structure/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group27/513274874/data-structure/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/group27/513274874/data-structure/src/com/coderising/litestruts/Struts.java b/group27/513274874/data-structure/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..02a8146b0c --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,254 @@ +package com.coderising.litestruts; + +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.File; +import java.io.FileNotFoundException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +public class Struts { + + private static Struts instance = null; + private static Map<String, StrutsXml> strutsXml; + + private Struts() { + } + + /** + * 单例模式初始化struts.xml,而不是每次跑runAction的时候都要初始化一次 + * + * @return + */ + public static Struts init() throws FileNotFoundException { + + if (instance == null) { + /** + * 0. 读取配置文件struts.xml + */ + //创建SAXReader对象 + SAXReader reader = new SAXReader(); + //读取文件 转换成Document + Document document = null; + try { + document = reader.read(new File("src/com/coding/coderising/litestruts/struts.xml")); + } catch (DocumentException e) { + e.printStackTrace(); + } + //获取根节点元素对象 + Element root = document.getRootElement(); + if ("struts".equals(root.getName())) { + strutsXml = new HashMap<String, StrutsXml>(); + + Iterator<Element> actions = root.elementIterator(); + while (actions.hasNext()) { + Element action = actions.next(); + List<Attribute> attrList = action.attributes(); + + String actionName = null; + StrutsXml xml = null; + if (!"action".equals(action.getName())) { + continue; + } + //遍历属性节点 + for (Attribute attribute : attrList) { + xml = new StrutsXml(); + if ("name".equals(attribute.getName())) { + actionName = attribute.getValue(); + } + if ("class".equals(attribute.getName())) { + xml.setClazz(attribute.getValue()); + //获取result信息 + Iterator<Element> results = action.elementIterator(); + while (results.hasNext()) { + Element result = results.next(); + List<Attribute> resultList = result.attributes(); + for (Attribute resultAttr : resultList) { + //System.out.println(resultAttr.getValue() + " ,"+result.getText()); + xml.getResult().put(resultAttr.getValue(), result.getText()); + } + } + + } + //System.out.println("属性"+attribute.getName() +":" + attribute.getValue()); + } + + strutsXml.put(actionName, xml); + } + } else { + throw new FileNotFoundException("not a struts XML file !"); + } + + + instance = new Struts(); + } + return instance; + } + + public static View runAction(String actionName, Map<String, String> parameters) { + + if (instance == null) return null; + if (actionName == null || "".equals(actionName.trim())) return null; + View view = new View(); + StrutsXml struts = strutsXml.get(actionName); + + Class clazz = null; + /** + * 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + * ("name"="test" , "password"="1234") ,那就应该调用 setName和setPassword方法 + */ + //获取相应处理的action + if (struts != null) { + String className = struts.getClazz(); + try { + clazz = Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } else { + throw new NullPointerException("action not found in struts file !"); + } + + if (clazz != null) { + Object action = null; + try { + action = clazz.newInstance(); + + //反射调用设置参数 + for (Map.Entry<String, String> entry : parameters.entrySet()) { + String para = entry.getKey(); + if (!checkField(clazz, para)) continue; + //根据习惯,类的属性首字母在调用时大写,例如属性名是 age,则类方法为getAge + PropertyDescriptor pd = new PropertyDescriptor(para, clazz); + + Method setMethod = pd.getWriteMethod();//获得set方法 + + setMethod.invoke(action, entry.getValue()); + + } + /** + * 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + */ + //执行execute() + Method excuteMethod = clazz.getDeclaredMethod("execute"); + String result = (String) excuteMethod.invoke(action); + //通过xml文件获取返回值 + String jsp = struts.getResult().get(result); + + if (jsp == null || jsp.trim().equals("")) { + throw new NullPointerException("the requested file is not found !"); + } + /** + * 3. 通过反射找到对象的所有getter方法(例如 getMessage), + * 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + * 放到View对象的parameters + */ + //执行get方法 + Map<String, String> viewMap = new HashMap<>(); + Field[] fields = clazz.getDeclaredFields();//获得属性 + + for (Field field : fields) { + String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1); + Method getMethod = clazz.getDeclaredMethod(getMethodName); + String returnVal = (String) getMethod.invoke(action); + viewMap.put(field.getName(), returnVal); + } + /** + * 4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, + * 放到View对象的jsp字段中。 + */ + view.setJsp(jsp); + view.setParameters(viewMap); + + } catch (IntrospectionException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } + } + + return view; + + + } + + private static boolean checkField(Class clazz, String fieldName) { + if (fieldName == null || fieldName.trim().equals("")) return false; + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + if (fieldName.equals(field.getName())) return true; + } + return false; + } + + + public static void main(String args[]) { + try { + Struts.init(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + Map<String, String> paras = new HashMap<>(); + paras.put("name", "test"); + paras.put("password", "1234"); + View view = Struts.runAction("login", paras); + } +} + +class StrutsXml { + private String actionName; + private String clazz; + private Map<String, String> result = new HashMap<>(); + + public StrutsXml(String actionName, String clazz, Map<String, String> result) { + this.actionName = actionName; + this.clazz = clazz; + this.result = result; + } + + public StrutsXml() { + } + + public String getActionName() { + return actionName; + } + + public void setActionName(String actionName) { + this.actionName = actionName; + } + + public String getClazz() { + return clazz; + } + + public void setClazz(String clazz) { + this.clazz = clazz; + } + + public Map<String, String> getResult() { + return result; + } + + public void setResult(Map<String, String> result) { + this.result = result; + } +} \ No newline at end of file diff --git a/group27/513274874/data-structure/src/com/coderising/litestruts/StrutsTest.java b/group27/513274874/data-structure/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..c6341d662d --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,53 @@ +package com.coderising.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + + + + + +public class StrutsTest { + @Before + public void before() throws Exception { + Struts.init(); + } + + @After + public void after() throws Exception { + } + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map<String,String> params = new HashMap<String,String>(); + 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<String,String> params = new HashMap<String,String>(); + 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/group27/513274874/data-structure/src/com/coderising/litestruts/View.java b/group27/513274874/data-structure/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group27/513274874/data-structure/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/group27/513274874/data-structure/src/com/coding/basic/ArrayList.java b/group27/513274874/data-structure/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..9e55e92529 --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/ArrayList.java @@ -0,0 +1,124 @@ + +package com.coding.basic; + +import java.util.Arrays; + +/** + * @autor zhougd 20170306 + * 数组实现ArrayList + */ +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData; + + //扩容默认值 + private static final int INCREAMENT_CAP = 10; + + //含参数的构造函数 + public ArrayList(int size, Object[] elementData) { + this.size = size; + this.elementData = elementData; + } + + //默认100容量的构造函数 + public ArrayList() { + this.size = 0; + this.elementData = new Object[100]; + } + + @Override + public void add(Object o) { + //判断超过容量自动扩容 + if (this.size + 1 > this.elementData.length) { + increase(); + } + this.elementData[size++] = o; + } + + @Override + public void add(int index, Object o) { + if (index < 0 || index > this.size) { + throw new IndexOutOfBoundsException("Index out of bound!"); + } + //判断超过容量自动扩容 + if (this.size + 1 > this.elementData.length) { + increase(); + } + this.size++; + //index后面数组后移一位 + for (int cur = this.size; cur > index; cur--) { + this.elementData[cur] = this.elementData[cur - 1]; + } + + this.elementData[index] = o; + + } + + public Object get(int index) { + if (index < 0 || index > this.size) { + throw new IndexOutOfBoundsException("Index out of bound!"); + } + return this.elementData[index]; + } + + public Object remove(int index) { + Object o = this.get(index); + + //index后面的数向前移动一位 + for (int cur = index + 1; cur < this.size; cur++) { + this.elementData[cur] = this.elementData[cur + 1]; + } + //最后一个元素删除 + this.elementData[this.size-1] = null; + + this.size--; + return o; + } + + public int size() { + return this.size + 1; + } + + public Iterator iterator() { + return new ArrayListIterator(); + } + + @Override + public String toString() { + String arrayStr = "ArrayList{ size = " + this.size() + " , "; + + arrayStr += "elementData=["; + for(int i = 0 ;i<this.size();i++){ + arrayStr += + i == this.size()-1 ? + elementData[i]+"]":elementData[i]+"," ; + } + arrayStr+= " }"; + return arrayStr; + + } + + private void increase() { + this.elementData = Arrays.copyOf(this.elementData, this.elementData.length + INCREAMENT_CAP); + } + + private class ArrayListIterator implements Iterator { + + private int currentIndex = 0; + private int count = size(); + + @Override + public boolean hasNext() { + return currentIndex < count-1; + } + + @Override + public Object next() { + currentIndex++; + return get(currentIndex); + } + } +} + diff --git a/group27/513274874/data-structure/src/com/coding/basic/BinaryTreeNode.java b/group27/513274874/data-structure/src/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group27/513274874/data-structure/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/group27/513274874/data-structure/src/com/coding/basic/Iterator.java b/group27/513274874/data-structure/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..06ef6311b2 --- /dev/null +++ b/group27/513274874/data-structure/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/group27/513274874/data-structure/src/com/coding/basic/List.java b/group27/513274874/data-structure/src/com/coding/basic/List.java new file mode 100644 index 0000000000..10d13b5832 --- /dev/null +++ b/group27/513274874/data-structure/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/group27/513274874/data-structure/src/com/coding/basic/Queue.java b/group27/513274874/data-structure/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..9dec7f059a --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/Queue.java @@ -0,0 +1,50 @@ + +package com.coding.basic; + +import com.coding.basic.linklist.LinkedList; + +/** + * author by zhougd 20170306 + * 链表实现队列 + */ +public class Queue { + private java.util.Queue a;; + /** + * 队列体,初始100个元素 + */ + private List queue = new LinkedList(); + + public Queue(){} + + /** + * 入队 + * @param o + */ + public void enQueue(Object o){ + queue.add(o); + } + + /** + * 出队 + * @return + */ + public Object deQueue(){ + return queue.remove(0); + } + + /** + * 队列是否为空 + * @return + */ + public boolean isEmpty(){ + return queue == null || queue.size() <= 0; + } + + /** + * 获取队列大小 + * @return + */ + public int size(){ + return queue.size(); + } +} diff --git a/group27/513274874/data-structure/src/com/coding/basic/Stack.java b/group27/513274874/data-structure/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..034e4c7215 --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/Stack.java @@ -0,0 +1,65 @@ + +package com.coding.basic; + +/** + * author zhougd 20170306 + * + */ +public class Stack { + private List elementData = new ArrayList(); + + + public Stack() { + } + + /** + * 入栈 + * @param o + */ + public void push(Object o){ + elementData.add(o); + } + + /** + * 出栈 + * @return + */ + public Object pop(){ + if(this.isEmpty()){ + throw new IndexOutOfBoundsException("stack is empty!"); + } + Object element = elementData.get(size()-1); + elementData.remove(size()-1); + return element; + } + + /** + * 查看栈顶元素 + * @return Object + */ + public Object peek(){ + if(this.isEmpty()){ + throw new IndexOutOfBoundsException("stack is empty!"); + } + Object element = elementData.get(size()-1); + return element; + } + + /** + * 查看栈是否为空 + * @return boolean + */ + public boolean isEmpty(){ + + return elementData == null || elementData.size()<=0; + + } + + /** + * 获取栈大小 + * @return + */ + public int size(){ + return elementData.size(); + } +} \ No newline at end of file diff --git a/group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtil.java b/group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..0adc748f61 --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,262 @@ +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 static void reverseArray(final int[] origin) { + int size = origin.length; + if (size <= 0) return; + + int[] newArray = copyOf(origin); + + for (int i = 0; i < size; i++) { + origin[i] = newArray[size - 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 size = oldArray.length; + int countZero = 0; + //首先判断数组中0的个数 + for (int i : oldArray) { + if (i == 0) countZero++; + } + int[] newArray = new int[size - countZero]; + //cur 命名newArray的游标 + int cur = 0; + for (int i = 0; i < size; i++) { + if (oldArray[i] == 0) continue; + newArray[cur++] = 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 static int[] merge(int[] array1, int[] array2) { + //判断数组是否为空 + int size1 = array1.length; + int size2 = array2.length; + if (size1 <= 0 || size2 <= 0) + return size1 <= 0 ? array2 : array1; + + //先将两个数组合并成一个数组 + int[] newArray = new int[size1 + size2]; + System.arraycopy(array1, 0, newArray, 0, size1); + System.arraycopy(array2, 0, newArray, size1, size2); + + + //对数组进行插入排序(假定array1已经是有序数组) + int in, out; + for (out = size1; out < newArray.length; out++) { + in = out; + int temp = newArray[out]; + + while (in > 0 && newArray[in - 1] >= temp) { + //右移 + newArray[in] = newArray[in - 1]; + --in; + } + newArray[in] = temp; + } + return newArray; + } + + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * + * @param oldArray + * @param size + * @return + */ + public static int[] grow(int[] oldArray, int size) { + int oldSize = oldArray.length; + if (oldSize == 0) return new int[size]; + + if (size <= 0) return oldArray; + + int[] newArray = new int[oldSize + size]; + System.arraycopy(oldArray, 0, newArray, 0, oldSize); + + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * + * @param max + * @return + */ + public static int[] fibonacci(int max) { + //先确定数组长度 + if (max == 1) return new int[]{}; + //这里的cur指的是数组的下标,从0开始,而不是数学函数1开始 + int cur = 2; + int val_1 = 1; + int val_2 = 1; + while (val_1 + val_2 <= max) { + int temp = val_1; + val_1 = val_2; + val_2 += temp; + ++cur; + } + + int[] newArray = new int[cur]; + for (int i = 0; i < cur; i++) { + if (i == 0 || i == 1) { + newArray[i] = 1; + continue; + } + newArray[i] = newArray[i - 1] + newArray[i - 2]; + + } + return newArray; + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * + * @param max + * @return + */ + public static int[] getPrimes(int max) { + //先确定数组长度 + //判断质数循环 + int count = 0; + for (int i = 1; i < max; i++) { + //去掉偶数 + if (i == 1 || (i % 2 == 0 && i != 2)) continue; + boolean flag = true; + for (int j = 3; j <= Math.sqrt(i); j += 2) { + if (i % j == 0) { + flag = false; + break; + } + } + if (flag) count++; + } + int[] newArray = new int[count]; + int cur = 0; + for (int i = 1; i < max; i++) { + //去掉偶数 + if (i == 1 || (i % 2 == 0 && i != 2)) continue; + //判断到开根号即可 + boolean flag = true; + for (int j = 3; j <= Math.sqrt(i); j += 2) { + if (i % j == 0) { + flag = false; + + } + } + if (flag) { + newArray[cur] = i; + ++cur; + } + + } + + + return newArray; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * + * @param max + * @return + */ + public static int[] getPerfectNumbers(int max) { + //求数组长度 + int count = 0; + for (int a = 1; a <= max; a++) { + int sum = 0; + for (int i = 1; i <= a / 2; i++) + if (a % i == 0) + sum += i; + if (a == sum) + ++count; + } + + int[] newArray = new int[count]; + int cur = 0; + for (int a = 1; a <= max; a++) { + int sum = 0; + for (int i = 1; i <= a / 2; i++) + if (a % i == 0) + sum += i; + if (a == sum) { + newArray[cur] = a; + ++cur; + } + } + + return newArray; + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * + * @param array + * @param seperator + * @return + */ + public static String join(int[] array, String seperator) { + int size = array.length; + if (size == 0) return ""; + StringBuffer sb = new StringBuffer(""); + for (int i = 0; i < size - 1; i++) { + sb.append(array[i]).append(seperator); + } + sb.append(array[size - 1]); + return sb.toString(); + } + + + /** + * 类私有函数,复制返回一个新的数组 + */ + private static int[] copyOf(int[] source) { + int size = source.length; + if (size <= 0) return null; + + int[] newArray = new int[size]; + //int[] ints = Arrays.copyOf(origin, size); + System.arraycopy(source, 0, newArray, 0, size); + return newArray; + } + + +} diff --git a/group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtilTest.java b/group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtilTest.java new file mode 100644 index 0000000000..7918ae41fe --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/array/ArrayUtilTest.java @@ -0,0 +1,110 @@ +package com.coding.basic.array; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * ArrayUtil Tester. + * + * @author <Authors name> + * @version 1.0 + * @since <pre>三月 14, 2017</pre> + */ +public class ArrayUtilTest { + + int[] testArray ; + + @Before + public void before() throws Exception { + } + + @After + public void after() throws Exception { + testArray = new int[]{}; + } + + /** + * Method: reverseArray(final int[] origin) + */ + @Test + public void testReverseArray() throws Exception { + testArray = new int[]{1,3,5,7,9,4,6}; + ArrayUtil.reverseArray(testArray); + Assert.assertArrayEquals(new int[]{6,4,9,7,5,3,1},testArray); + } + + + /** + * Method: removeZero(int[] oldArray) + */ + @Test + public void testRemoveZero() throws Exception { + testArray = new int[]{1,3,0,7,0,4,6}; + int[] newArray = ArrayUtil.removeZero(testArray); + Assert.assertArrayEquals(new int[]{1,3,7,4,6}, newArray); + } + + /** + * Method: merge(int[] array1, int[] array2) + */ + @Test + public void testMerge() throws Exception { + int[] testArray1 = new int[]{1,3,6,8,9}; + int[] testArray2 = new int[]{2,3,3,10,12}; + + int[] mergedArray = ArrayUtil.merge(testArray1,testArray2); + Assert.assertArrayEquals(new int[]{1,2,3,3,3,6,8,9,10,12},mergedArray); + } + + /** + * Method: grow(int[] oldArray, int size) + */ + @Test + public void testGrow() throws Exception { + testArray = new int[]{1,2,3,4,5,6}; + int[] grewArray = ArrayUtil.grow(testArray,4); + Assert.assertArrayEquals(new int[]{1,2,3,4,5,6,0,0,0,0},grewArray); + + } + + /** + * Method: fibonacci(int max) + */ + @Test + public void testFibonacci() throws Exception { + int[] fibArray = ArrayUtil.fibonacci(20); + Assert.assertArrayEquals(new int[]{1,1,2,3,5,8,13},fibArray); + } + + /** + * Method: getPrimes(int max) + */ + @Test + public void testGetPrimes() throws Exception { + testArray = ArrayUtil.getPrimes(23); + Assert.assertArrayEquals(new int[]{2,3,5,7,11,13,17,19},testArray); + } + + /** + * Method: getPerfectNumbers(int max) + */ + @Test + public void testGetPerfectNumbers() throws Exception { + testArray = ArrayUtil.getPerfectNumbers(1000); + Assert.assertArrayEquals(new int[]{6,28,496},testArray); + } + + /** + * Method: join(int[] array, String seperator) + */ + @Test + public void testJoin() throws Exception { + testArray = new int[]{1,2,3,5,7,9,12}; + String seperated = ArrayUtil.join(testArray,"-"); + Assert.assertEquals("1-2-3-5-7-9-12",seperated); + } + + +} diff --git a/group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java b/group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..4414a8eb6f --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,158 @@ +package com.coding.basic.linklist; + +import java.util.Objects; + +/** + * 用双向链表实现LRU算法 + * + * @author liuxin + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + + public boolean hasNext() { + return next != null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return Objects.equals(pageNum, node.pageNum); + } + + @Override + public int hashCode() { + return Objects.hash(pageNum); + } + } + + private int capacity;//最大存储个数 + private int cur;//当前存储个数 + + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param pageNum + * @return + */ + public void access(int pageNum) { + if(this.cur == 0 ) { + Node node = new Node(); + node.pageNum = pageNum; + addFirst(node); + return; + } + + if (get(pageNum) != null) { + pop(pageNum); + } else { + Node node = new Node(); + node.pageNum = pageNum; + add(node); + } + } + + private void add(Node node) { + addFirst(node); + } + + private Node get(int pageNum) { + Node val = this.first; + while (val.hasNext()) { + if (val.pageNum == pageNum) { + return val; + } + val = val.next; + } + return null; + } + + private void addFirst(Node node) { + if(cur == 0){ + this.first = node; + this.last = node; + }else { + Node oldFirst = this.first; + this.first = node; + node.prev = null; + node.next = oldFirst; + + oldFirst.prev = node; + } + this.cur++; + + if (cur > capacity) { + removeLast(); + } + } + private void removeLast(){ + Node oldLast = this.last; + this.last = oldLast.prev; + oldLast.prev.next = null; + + oldLast = null; + } + + /** + * 将节点变成first + * + * @param pageNum + */ + private void pop(int pageNum) { + Node node = this.get(pageNum); + + //根据node的位置确定如何位移 + if (node.equals(this.first)) { + return; + } else { + Node oldPre = node.prev; + Node oldNext = node.next; + Node oldFirst = this.first; + + this.first = node; + node.prev = null; + node.next = oldFirst; + + oldPre.next = oldNext; + oldNext.prev = oldPre; + + + } + + } + + + 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/group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..374cfafecf --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,52 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess3() { + 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()); + } + + @Test + public void testAccess5() { + LRUPageFrame frame = new LRUPageFrame(5); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0,7", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1,7", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1,7", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2,1,7", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2,1,7", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3,2,1", frame.toString()); + } + +} diff --git a/group27/513274874/data-structure/src/com/coding/basic/linklist/LinkedList.java b/group27/513274874/data-structure/src/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..e6d400f483 --- /dev/null +++ b/group27/513274874/data-structure/src/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,268 @@ + +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +import java.util.NoSuchElementException; + +/** + * @author zhougd 20170306 + * 单向链表实现LinkedList + */ + +public class LinkedList implements List { + java.util.LinkedList a; + /** + * 第一个元素 + */ + private Node head; + + /** + * 最后一个元素 + */ + private Node tail; + + /** + * 元素容量 + */ + private int size = 0; + + public void add(Object o){ + Node node = new Node(o); + //判断是否链表为空 + if(this.size() == 0){ + this.addFirst(node); + }else{ + this.addLast(node); + } + + } + public void add(int index , Object o){ + checkIndex(index); + + Node oldNode= this.getNode(index); + Object oldObject = oldNode.getData(); + Node next = oldNode.getNext(); + + //将原位置修改为新元素 + oldNode.setData(o); + //设置下一个元素 + oldNode.setNext(new Node(oldObject)); + //设置下一个元素的下一个元素 + oldNode.getNext().setNext(next); + + size ++; + } + + public Object get(int index){ + checkIndex(index); + return this.getNode(index).getData(); + } + + public Object remove(int index){ + checkIndex(index); + //获取到当前元素和下一个元素 + //把当前元素的值设置成下一个元素的值,删除掉下一个元素,这样的话,不必管上一个元素是什么,是不是第一个元素 + Node node = this.getNode(index); + Object data = node.getData(); + Node nextNode = this.getNode(index + 1); + node.setData(nextNode.getData()); + node.setNext(nextNode.getNext()); + + return data; + } + + public int size(){ + return this.size(); + } + + public void addFirst(Object o){ + Node node = new Node(o); + //原头变为第二 + Node temp = this.head; + this.head = node; + node.next = temp; + size++; + } + public void addLast(Object o){ + Node node = new Node(o); + Node t = this.tail; + if(t == null){ + this.head = node; + }else{ + this.tail.next = node; + this.tail = node; + } + size++; + } + public Object removeFirst(){ + Node head = this.head; + if(head == null){ + throw new NoSuchElementException("No such element !"); + } + this.head = this.head.getNext(); + size--; + return head ; + } + + public Object removeLast(){ + Node node ; + if(this.tail == null){ + throw new NoSuchElementException("No such element !"); + } + node = this.tail; + if(this.head ==this.tail){ + node = this.head; + this.head = null; + this.size = 0; + }else{ + //获取尾元素的上一个元素 + this.tail = this.getNode(this.size-2); + this.tail.setNext(null); + this.size--; + } + + return node; + } + + public Iterator iterator(){ + return new LinkedListIterator(); + } + + private void checkIndex(int index){ + if(index < 0 || index >size()){ + throw new IndexOutOfBoundsException("Index out of bound !"); + } + } + + private Node getNode(int index ){ + + Node node = this.head; + for(int i = 0 ;i<size();i++){ + node = node.next; + } + return node; + } + + private class LinkedListIterator implements Iterator{ + + private int currentIndex = 0; + private int count = size(); + + @Override + public boolean hasNext() { + return currentIndex < count-1; + } + + @Override + public Object next() { + currentIndex++; + return get(currentIndex); + } + } + + private static class Node{ + Object data; + Node next; + + public Node(Object data) { + this.data = data; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public Node getNext() { + return next; + } + + public void setNext(Node next) { + this.next = 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/data-structure/test/com/coding/basic/ArrayListTest.java b/group27/513274874/data-structure/test/com/coding/basic/ArrayListTest.java new file mode 100644 index 0000000000..251f5a8d92 --- /dev/null +++ b/group27/513274874/data-structure/test/com/coding/basic/ArrayListTest.java @@ -0,0 +1,151 @@ +package com.coding.basic; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Random; + +/** +* ArrayList Tester. +* +* @author <Authors name> +* @since <pre>三月 6, 2017</pre> +* @version 1.0 +*/ +public class ArrayListTest { + +@Before +public void before() throws Exception { + +} + +@After +public void after() throws Exception { +} + +/** +* +* Method: add(Object o) +* +*/ +@Test +public void testAddO() throws Exception { + ArrayList arrayList = new com.coding.basic.ArrayList(); + arrayList.add(100); + arrayList.add(20); + + for(int i = 1 ;i <= 200 ;i++){ + arrayList.add(new Random().nextInt(100)); + } + + System.out.println(arrayList); + + assert(arrayList.size() == 202); +} + +/** +* +* Method: add(int index, Object o) +* +*/ +@Test +public void testAddForIndexO() throws Exception { + ArrayList arrayList = new com.coding.basic.ArrayList(); + arrayList.add(1); + arrayList.add(2); + arrayList.add(3); + arrayList.add(4); + arrayList.add(5); + + arrayList.add(3,"添加"); + //arrayList.add(100,3); + assert(arrayList.size() == 6); + System.out.println(arrayList); +} + +/** +* +* Method: get(int index) +* +*/ +@Test +public void testGet() throws Exception { + ArrayList arrayList = new com.coding.basic.ArrayList(); + arrayList.add(1); + arrayList.add(2); + arrayList.add(3); + arrayList.add(4); + arrayList.add(5); + + assert(((Integer)arrayList.get(3)).intValue() == 4); +} + +/** +* +* Method: remove(int index) +* +*/ +@Test +public void testRemove() throws Exception { + ArrayList arrayList = new com.coding.basic.ArrayList(); + arrayList.add(1); + arrayList.add(2); + arrayList.add(3); + arrayList.add(4); + arrayList.add(5); + + arrayList.remove(3); + //arrayList.add(100,3); + assert(arrayList.size() == 4); + System.out.println(arrayList); +} + +/** +* +* Method: size() +* +*/ +@Test +public void testSize() throws Exception { +//TODO: Test goes here... + + ArrayList arrayList = new com.coding.basic.ArrayList(); + arrayList.add(100); + arrayList.add(20); + + for(int i = 1 ;i <= 200 ;i++){ + arrayList.add(new Random().nextInt(100)); + } + + System.out.println(arrayList); + + assert(arrayList.size() == 202); +} + +/** +* +* Method: iterator() +* +*/ +@Test +public void testIterator() throws Exception { +//TODO: Test goes here... + ArrayList arrayList = new com.coding.basic.ArrayList(); + arrayList.add(100); + arrayList.add(20); + + for(int i = 1 ;i <= 200 ;i++){ + arrayList.add(new Random().nextInt(100)); + } + System.out.println(arrayList); + + Iterator iterator = arrayList.iterator(); + while(iterator.hasNext()){ + System.out.print(iterator.next() + ","); + } + + assert(arrayList.size() == 202); +} + +} diff --git a/group27/513274874/homework/.project b/group27/513274874/homework/.project index b6d8ce6204..8a1c96cafa 100644 --- a/group27/513274874/homework/.project +++ b/group27/513274874/homework/.project @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <projectDescription> - <name>coding2017</name> + <name>ThirdHomework</name> <comment></comment> <projects> </projects> 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..04cf3e4fe7 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java +++ b/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java @@ -1,20 +1,38 @@ -package com.coderising.download; +package com.coding.coderising.download; + + +import com.coding.coderising.download.api.Connection; + +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; + // 将下载到的字节输出到raf中 + private RandomAccessFile raf; + public DownloadThread( Connection conn, int startPos, int endPos){ this.conn = conn; + this.startPos = startPos; this.endPos = endPos; + this.filePath = filePath; } - 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..7a010983f8 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,11 @@ -package com.coderising.download; +package com.coding.coderising.download; + + +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; -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 { @@ -14,7 +16,10 @@ public class FileDownloader { ConnectionManager cm; - + private final static int thread_count = 3; + + private final static String BASE_PATH = "E:\\"; + public FileDownloader(String _url) { this.url = _url; @@ -23,13 +28,18 @@ public FileDownloader(String _url) { public void execute(){ // 在这里实现你的代码, 注意: 需要用多线程实现下载 // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 - // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) - // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 - // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // (1) ConnectionManager , 可以打开一个连接, + //通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, + //调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, + //这样客户端就能收到通知。 // 具体的实现思路: - // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 1. 需要调用ConnectionManager的open方法打开连接, + //然后通过Connection.getContentLength方法获得文件的长度 // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 - // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, + //返回值是byte[]数组 // 3. 把byte数组写入到文件中 // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 @@ -41,10 +51,54 @@ public void execute(){ int length = conn.getContentLength(); - new DownloadThread(conn,0,length-1).start(); + String targetPath = BASE_PATH + "targetfile." + url.substring(url.lastIndexOf(".") + 1); + + int startPos = 0; + + int endPos = 0; + + List<DownloadThread> list = new ArrayList<DownloadThread>(); + + for(int i = 0; i < thread_count; i++){ + + conn = cm.open(url); + + startPos = i * (length / thread_count); + + endPos = (i == thread_count - 1) ? length - 1 : (i + 1) * (length / thread_count) - 1; + + DownloadThread thread = new DownloadThread(conn, startPos, endPos, targetPath); + + list.add(thread); + + thread.start(); + } + + // 调用线程的join方法,保证所有的线程都结束后再发出结束通知 + + for (int i = 0; i < list.size(); i++) { + + try { + + list.get(i).join(); + + } catch (InterruptedException e) { + + // TODO Auto-generated catch block + + e.printStackTrace(); + + } + + } + + + + listener.notifyFinished(); } catch (ConnectionException e) { e.printStackTrace(); + }finally{ if(conn != null){ conn.close(); 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..60aa517b5b 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; @@ -21,7 +21,7 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "http://localhost:8080/test.jpg"; + String url = "C:/Users/苏磊/Desktop/R%T[DQRU~@$6TKZ7)TD81JW.png"; FileDownloader downloader = new FileDownloader(url); 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/impl/ConnectionImpl.java b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java index 32f03efdc7..a56ee74918 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,104 @@ -package com.coderising.download.impl; +package com.coding.coderising.download.impl; -import java.io.IOException; -import com.coderising.download.api.Connection; +import com.coding.coderising.download.api.Connection; -public class ConnectionImpl implements Connection{ - @Override - public byte[] read(int startPos, int endPos) throws IOException { - - return null; - } +import java.io.*; +import java.net.URL; +import java.net.URLConnection; - @Override - public int getContentLength() { - - return 0; - } +public class ConnectionImpl implements Connection { + private URL url; - @Override - public void close() { - - - } + // 定义字节数组(取水的竹筒)的长度 + private final int BUFF_LEN = 32; + + // 下载资源对应的输入流 + private InputStream is; + + + + 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..5250910126 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,33 @@ -package com.coderising.download.impl; +package com.coding.coderising.download.impl; + + +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; -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; + + + 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/513274874/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group27/513274874/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..15986ec3d2 --- /dev/null +++ b/group27/513274874/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,57 @@ +package com.coderising.jvm.loader; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + +public class ClassFileLoader { + + private List<String> clzPaths = new ArrayList<String>(); + private static final String CLASS_SUFFIX = ".class"; + private static final String PATH_SEPARATOR = System.getProperty("file.separator"); + + public byte[] readBinaryCode(String className) { + + if (className == null || className.trim().equals("")) { + throw new IllegalArgumentException("package and file name can't be blank!"); + } + //扫描classpath,找到文件即停止扫描,找不到就报错 + String packageName = className.replace(".", PATH_SEPARATOR); + String clazzURL = packageName + CLASS_SUFFIX; + File file = null; + for (String path : clzPaths) { + file = new File(path + clazzURL); + if (file.isDirectory() && file.length() > 0) break; + } + byte[] clazzByte = new byte[0]; + try { + FileInputStream fis = new FileInputStream(file); + DataInputStream data_in = new DataInputStream(fis); + clazzByte = new byte[(int) file.length()]; + data_in.read(clazzByte, 0, (int) file.length()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return clazzByte; + } + + + public void addClassPath(String path) { + if (null == path || path.trim().equals("")) return; + clzPaths.add(path); + } + + + public String getClassPath() { + String clazzPaths = ""; + for (String clazzPath : clzPaths) { + clazzPaths += clazzPath + ";"; + } + return clazzPaths; + } + + } diff --git a/group27/513274874/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group27/513274874/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..0737dd702e --- /dev/null +++ b/group27/513274874/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,91 @@ +package com.coderising.jvm.test; + +import com.coderising.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/guodongchow/Desktop/coding2017/projects/mini-jvm/bin/"; + static String path2 = "/Users/guodongchow/bin"; + + + + @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/group27/513274874/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java b/group27/513274874/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..12e3d7efdd --- /dev/null +++ b/group27/513274874/mini-jvm/src/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/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<list.size(); i++){ + result[i] = (Integer)this.get((Integer)list.get(i)); + } + return result; + } + + /** + * ֪еԪֵУԵ洢ṹ + * ӵǰɾlistBгֵԪ + + * @param list + */ + + public void subtract(LinkedList list){ + + + out: + for (int i = 0; i < list.size(); i++) { + Integer temp1 = (Integer)list.get(i); + for(int j = 0; j < this.size(); j++){ + Integer temp2 = (Integer)this.get(j); + if(temp1.equals(temp2)){ + this.remove(j); + continue out; + } + + + } + + } + + } + + /** + * ֪ǰеԪֵУԵ洢ṹ + * ɾֵͬĶԪأʹòԱԪصֵͬ + */ + public void removeDuplicateValues(){ + LinkedList temp = new LinkedList(); + for(int i = 0; i < this.size(); i++){ + if(i == 0){ + temp.add(this.get(i)); + }else{ + if(this.get(i) != temp.get(temp.size()-1)){ + temp.add(this.get(i)); + } + } + } + this.clear(); + + for(int i = 0; i<temp.size();i++){ + this.add(temp.get(i)); + } + + + + } + + /** + * ֪еԪֵУԵ洢ṹ + * дһЧ㷨ɾֵminСmaxԪأдԪأ + * @param min + * @param max + */ + public void removeRange(int min, int max){ + int indexMin = -1; + int indexMax = -1; + int countForMin = 0; + int countForMax = 0; + + for(int i = 0; i < this.size(); i++){ + + Integer eleFront = (Integer)this.get(i); + Integer eleBack = (Integer)this.get(this.size()-1-i); + if(eleFront > 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..fedb243604 --- /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..70bd34e37f --- /dev/null +++ b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java @@ -0,0 +1,136 @@ +package com.coding.basic.stack; +import java.util.Stack; +public class StackUtil { + + public static void bad_reverse(Stack<Integer> s) { + if(s == null || s.isEmpty()){ + return; + } + Stack<Integer> tmpStack = new Stack(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + + s = tmpStack; + + } + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack<Integer> s) { + if(s == null || s.isEmpty()){ + return; + } + Integer top = s.pop(); + reverse(s); + addToBottom(s,top); + + + } + public static void addToBottom(Stack<Integer> s, Integer value){ + if(s.isEmpty()){ + s.push(value); + } else{ + Integer top = s.pop(); + addToBottom(s,value); + s.push(top); + } + + } + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + + while(!s.isEmpty()){ + Object value = s.pop(); + if(!value.equals(o)){ + tmpStack.push(value); + } + } + + while(!tmpStack.isEmpty()){ + s.push(tmpStack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + + if(s == null || s.isEmpty() || s.size()<len || len <=0 ){ + return null; + } + + Stack tmpStack = new Stack(); + int i = 0; + Object[] result = new Object[len]; + while(!s.isEmpty()){ + Object value = s.pop(); + tmpStack.push(value); + result[i++] = value; + if(i == len){ + break; + } + } + + return result; + } + /** + * 字符串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){ + + Stack<Character> stack = new Stack(); + for(int i=0;i<s.length();i++){ + char c = s.charAt(i); + + if(c == '(' || c =='[' || c == '{'){ + + stack.push(c); + + } else if( c == ')'){ + + char topChar = stack.pop(); + if(topChar != '('){ + return false; + } + + } else if( c == ']'){ + + char topChar = stack.pop(); + if(topChar != '['){ + return false; + } + + } else if( c == '}'){ + + char topChar = stack.pop(); + if(topChar != '{'){ + return false; + } + + } + } + return stack.size() == 0; + } + + +} diff --git a/liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java b/liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java new file mode 100644 index 0000000000..99dd8450fe --- /dev/null +++ b/liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java @@ -0,0 +1,78 @@ +package com.coding.basic.stack; + +import static org.junit.Assert.fail; + +import java.util.Stack; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +public class StackUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAddToBottom() { + Stack<Integer> s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + + StackUtil.addToBottom(s, 0); + + Assert.assertEquals("[0, 1, 2, 3]", s.toString()); + + } + @Test + public void testReverse() { + Stack<Integer> s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString()); + StackUtil.reverse(s); + Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString()); + } + + @Test + public void testRemove() { + Stack<Integer> s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + StackUtil.remove(s, 2); + Assert.assertEquals("[1, 3]", s.toString()); + } + + @Test + public void testGetTop() { + Stack<Integer> s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + s.push(4); + s.push(5); + { + Object[] values = StackUtil.getTop(s, 3); + Assert.assertEquals(5, values[0]); + Assert.assertEquals(4, values[1]); + Assert.assertEquals(3, values[2]); + } + } + + @Test + public void testIsValidPairs() { + Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])")); + Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})")); + } + +} diff --git a/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..a089a2b2c0 --- /dev/null +++ b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java @@ -0,0 +1,18 @@ +package com.coding.basic.stack.expr; + +public class InfixExpr { + String expr = null; + + public InfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + + return 0.0f; + } + + + + +} diff --git a/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..20f52b4c63 --- /dev/null +++ b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,48 @@ +package com.coding.basic.stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..88f60c77f6 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java @@ -0,0 +1,19 @@ +package com.coderising.jvm.attr; + +public abstract class AttributeInfo { + public static final String CODE = "Code"; + public static final String CONST_VALUE = "ConstantValue"; + public static final String EXCEPTIONS = "Exceptions"; + public static final String LINE_NUM_TABLE = "LineNumberTable"; + public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; + public static final String STACK_MAP_TABLE = "StackMapTable"; + int attrNameIndex; + int attrLen ; + public AttributeInfo(int attrNameIndex, int attrLen) { + + this.attrNameIndex = attrNameIndex; + this.attrLen = attrLen; + } + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..ee7d423c3b --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.attr; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.loader.ByteCodeIterator; + + +public class CodeAttr extends AttributeInfo { + private int maxStack ; + private int maxLocals ; + private int codeLen ; + private String code; + public String getCode() { + return code; + } + + //private ByteCodeCommand[] cmds ; + //public ByteCodeCommand[] getCmds() { + // return cmds; + //} + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + + public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + super(attrNameIndex, attrLen); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.codeLen = codeLen; + this.code = code; + //this.cmds = cmds; + } + + public void setLineNumberTable(LineNumberTable t) { + this.lineNumTable = t; + } + + public void setLocalVariableTable(LocalVariableTable t) { + this.localVarTable = t; + } + + public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ + + + return null; + } + private void setStackMapTable(StackMapTable t) { + this.stackMapTable = t; + + } + + + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..d88752e323 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java @@ -0,0 +1,42 @@ +package com.coderising.jvm.attr; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LineNumberTable extends AttributeInfo { + List<LineNumberItem> items = new ArrayList<LineNumberItem>(); + + private static class LineNumberItem{ + int startPC; + int lineNum; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLineNum() { + return lineNum; + } + public void setLineNum(int lineNum) { + this.lineNum = lineNum; + } + } + public void addLineNumberItem(LineNumberItem item){ + this.items.add(item); + } + public LineNumberTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + + return null; + } + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java new file mode 100644 index 0000000000..962c3b8bc4 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java @@ -0,0 +1,39 @@ +package com.coderising.jvm.attr; + +public class LocalVariableItem { + private int startPC; + private int length; + private int nameIndex; + private int descIndex; + private int index; + public int getStartPC() { + return startPC; + } + public void setStartPC(int startPC) { + this.startPC = startPC; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getNameIndex() { + return nameIndex; + } + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + public int getDescIndex() { + return descIndex; + } + public void setDescIndex(int descIndex) { + this.descIndex = descIndex; + } + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..e4d3df0e77 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java @@ -0,0 +1,28 @@ +package com.coderising.jvm.attr; + + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.constant.ConstantPool; + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class LocalVariableTable extends AttributeInfo{ + + List<LocalVariableItem> items = new ArrayList<LocalVariableItem>(); + + public LocalVariableTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static LocalVariableTable parse(ByteCodeIterator iter){ + + return null; + } + private void addLocalVariableItem(LocalVariableItem item) { + this.items.add(item); + } + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..18f2ad0360 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java @@ -0,0 +1,30 @@ +package com.coderising.jvm.attr; + + +import com.coderising.jvm.loader.ByteCodeIterator; + +public class StackMapTable extends AttributeInfo{ + + private String originalCode; + + public StackMapTable(int attrNameIndex, int attrLen) { + super(attrNameIndex, attrLen); + } + + public static StackMapTable parse(ByteCodeIterator iter){ + int index = iter.nextU2ToInt(); + int len = iter.nextU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.nextUxToHexString(len); + t.setOriginalCode(code); + + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} 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..4755266987 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.clz; + +import java.util.ArrayList; +import java.util.List; + +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class ClassFile { + + private int minorVersion; + private int majorVersion; + + private AccessFlag accessFlag; + private ClassIndex clzIndex; + private ConstantPool pool; + private List<Field> fields = new ArrayList<Field>(); + private List<Method> methods = new ArrayList<Method>(); + + 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 addField(Field f){ + this.fields.add(f); + } + public List<Field> getFields(){ + return this.fields; + } + public void addMethod(Method m){ + this.methods.add(m); + } + public List<Method> getMethods() { + return methods; + } + + + 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<ConstantInfo> constantInfos = new ArrayList<ConstantInfo>(); + + + 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/field/Field.java b/liuxin/mini-jvm/src/com/coderising/jvm/field/Field.java new file mode 100644 index 0000000000..0d1c64587c --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/field/Field.java @@ -0,0 +1,33 @@ +package com.coderising.jvm.field; + +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ByteCodeIterator; + + +public class Field { + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + + + private ConstantPool pool; + + public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) { + + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + this.pool = pool; + } + + + + + public static Field parse(ConstantPool pool,ByteCodeIterator iter){ + + return null; + } + +} 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..6fb5570dff --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,57 @@ +package com.coderising.jvm.loader; + +import java.util.Arrays; + +import com.coderising.jvm.util.Util; + +public class ByteCodeIterator { + byte[] codes; + int pos = 0; + + ByteCodeIterator(byte[] codes) { + this.codes = codes; + } + + + + public byte[] getBytes(int len) { + if (pos + len >= codes.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + byte[] data = Arrays.copyOfRange(codes, pos, pos + len); + pos += len; + return data; + } + + public int nextU1toInt() { + + return Util.byteToInt(new byte[] { codes[pos++] }); + } + + public int nextU2ToInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++] }); + } + + public int nextU4ToInt() { + return Util.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }); + } + + public String nextU4ToHexString() { + return Util.byteToHexString((new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] })); + } + + public String nextUxToHexString(int len) { + byte[] tmp = new byte[len]; + + for (int i = 0; i < len; i++) { + tmp[i] = codes[pos++]; + } + return Util.byteToHexString(tmp).toLowerCase(); + + } + + public void back(int n) { + this.pos -= n; + } +} 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<this.clzPaths.size();i++){ + buffer.append(this.clzPaths.get(i)); + if(i<this.clzPaths.size()-1){ + buffer.append(";"); + } + } + return buffer.toString(); + } + private byte[] loadClassFile_V1(String clzFileName) { + + BufferedInputStream bis = null; + + try { + + File f = new File(clzFileName); + + + bis = new BufferedInputStream(new FileInputStream(f)); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + + byte[] buffer = new byte[1024]; + int length = -1; + + while((length = bis.read(buffer)) != -1){ + bos.write(buffer, 0, length); + } + + byte [] codes = bos.toByteArray(); + + return codes; + + } catch(IOException e){ + e.printStackTrace(); + + } finally{ + if(bis != null){ + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + + } + -} +} \ No newline at end of file diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..a30cb22ad1 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java @@ -0,0 +1,151 @@ +package com.coderising.jvm.loader; + +import java.io.UnsupportedEncodingException; + +import com.coderising.jvm.clz.AccessFlag; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.FieldRefInfo; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.NullConstantInfo; +import com.coderising.jvm.constant.StringInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; +import com.coderising.jvm.method.Method; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + + + ClassFile clzFile = new ClassFile(); + + ByteCodeIterator iter = new ByteCodeIterator(codes); + + String magicNumber = iter.nextU4ToHexString(); + + if (!"cafebabe".equals(magicNumber)) { + return null; + } + + clzFile.setMinorVersion(iter.nextU2ToInt()); + clzFile.setMajorVersion(iter.nextU2ToInt()); + + ConstantPool pool = parseConstantPool(iter); + clzFile.setConstPool(pool); + + AccessFlag flag = parseAccessFlag(iter); + clzFile.setAccessFlag(flag); + + ClassIndex clzIndex = parseClassInfex(iter); + clzFile.setClassIndex(clzIndex); + + parseInterfaces(iter); + + + return clzFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + + AccessFlag flag = new AccessFlag(iter.nextU2ToInt()); + // System.out.println("Is public class: " + flag.isPublicClass()); + // System.out.println("Is final class : " + flag.isFinalClass()); + + return flag; + } + + private ClassIndex parseClassInfex(ByteCodeIterator iter) { + + int thisClassIndex = iter.nextU2ToInt(); + int superClassIndex = iter.nextU2ToInt(); + + ClassIndex clzIndex = new ClassIndex(); + + clzIndex.setThisClassIndex(thisClassIndex); + clzIndex.setSuperClassIndex(superClassIndex); + + return clzIndex; + + } + + private ConstantPool parseConstantPool(ByteCodeIterator iter) { + + int constPoolCount = iter.nextU2ToInt(); + + System.out.println("Constant Pool Count :" + constPoolCount); + + ConstantPool pool = new ConstantPool(); + + pool.addConstantInfo(new NullConstantInfo()); + + for (int i = 1; i <= constPoolCount - 1; i++) { + + int tag = iter.nextU1toInt(); + + if (tag == 7) { + // Class Info + int utf8Index = iter.nextU2ToInt(); + ClassInfo clzInfo = new ClassInfo(pool); + clzInfo.setUtf8Index(utf8Index); + + pool.addConstantInfo(clzInfo); + } else if (tag == 1) { + // UTF-8 String + int len = iter.nextU2ToInt(); + byte[] data = iter.getBytes(len); + String value = null; + try { + value = new String(data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + UTF8Info utf8Str = new UTF8Info(pool); + utf8Str.setLength(len); + utf8Str.setValue(value); + pool.addConstantInfo(utf8Str); + }else if (tag == 8) { + StringInfo info = new StringInfo(pool); + info.setIndex(iter.nextU2ToInt()); + pool.addConstantInfo(info); + } else if (tag == 9) { + FieldRefInfo field = new FieldRefInfo(pool); + field.setClassInfoIndex(iter.nextU2ToInt()); + field.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(field); + } else if (tag == 10) { + // MethodRef + MethodRefInfo method = new MethodRefInfo(pool); + method.setClassInfoIndex(iter.nextU2ToInt()); + method.setNameAndTypeIndex(iter.nextU2ToInt()); + pool.addConstantInfo(method); + } else if (tag == 12) { + // Name and Type Info + NameAndTypeInfo nameType = new NameAndTypeInfo(pool); + nameType.setIndex1(iter.nextU2ToInt()); + nameType.setIndex2(iter.nextU2ToInt()); + pool.addConstantInfo(nameType); + } else { + throw new RuntimeException("the constant pool tag " + tag + " has not been implemented yet."); + } + } + + System.out.println("Finished reading Constant pool "); + + return pool; + } + private void parseInterfaces(ByteCodeIterator iter) { + int interfaceCount = iter.nextU2ToInt(); + + System.out.println("interfaceCount:" + interfaceCount); + + // TODO : 如果实现了interface, 这里需要解析 + } + + + +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java b/liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java new file mode 100644 index 0000000000..b57ef592d2 --- /dev/null +++ b/liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java @@ -0,0 +1,57 @@ +package com.coderising.jvm.method; + +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.attr.AttributeInfo; +import com.coderising.jvm.attr.CodeAttr; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.loader.ByteCodeIterator; + + + +public class Method { + + private int accessFlag; + private int nameIndex; + private int descriptorIndex; + + private CodeAttr codeAttr; + + private ClassFile clzFile; + + + public ClassFile getClzFile() { + return clzFile; + } + + public int getNameIndex() { + return nameIndex; + } + public int getDescriptorIndex() { + return descriptorIndex; + } + + public CodeAttr getCodeAttr() { + return codeAttr; + } + + public void setCodeAttr(CodeAttr code) { + this.codeAttr = code; + } + + public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) { + this.clzFile = clzFile; + this.accessFlag = accessFlag; + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + + + + public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ + return null; + + } +} diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java index a05534b210..c29ff5181f 100644 --- a/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java +++ b/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -1,11 +1,22 @@ package com.coderising.jvm.test; +import java.util.List; + import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import com.coderising.jvm.clz.ClassFile; +import com.coderising.jvm.clz.ClassIndex; +import com.coderising.jvm.constant.ClassInfo; +import com.coderising.jvm.constant.ConstantPool; +import com.coderising.jvm.constant.MethodRefInfo; +import com.coderising.jvm.constant.NameAndTypeInfo; +import com.coderising.jvm.constant.UTF8Info; +import com.coderising.jvm.field.Field; import com.coderising.jvm.loader.ClassFileLoader; +import com.coderising.jvm.method.Method; @@ -14,9 +25,20 @@ public class ClassFileloaderTest { + private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; + static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; static String path2 = "C:\temp"; + static ClassFile clzFile = null; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } @Before @@ -72,21 +94,184 @@ public void testMagicNumber(){ + 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(); + } + /** + * ---------------------------------------------------------------------- + */ - 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); + @Test + public void testVersion(){ + + Assert.assertEquals(0, clzFile.getMinorVersion()); + Assert.assertEquals(52, clzFile.getMajorVersion()); + + } + + @Test + public void testConstantPool(){ + + + ConstantPool pool = clzFile.getConstantPool(); + + Assert.assertEquals(53, pool.getSize()); + + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); + Assert.assertEquals(2, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); + Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); } - return buffer.toString(); - } + { + ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); + Assert.assertEquals(4, clzInfo.getUtf8Index()); + + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); + Assert.assertEquals("java/lang/Object", utf8Info.getValue()); + } + { + UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); + Assert.assertEquals("name", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(6); + Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(7); + Assert.assertEquals("age", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(8); + Assert.assertEquals("I", utf8Info.getValue()); + + utf8Info = (UTF8Info) pool.getConstantInfo(9); + Assert.assertEquals("<init>", 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()); + } + + /** + * 下面是第三次JVM课应实现的测试用例 + */ + @Test + public void testReadFields(){ + + List<Field> fields = clzFile.getFields(); + Assert.assertEquals(2, fields.size()); + { + Field f = fields.get(0); + Assert.assertEquals("name:Ljava/lang/String;", f.toString()); + } + { + Field f = fields.get(1); + Assert.assertEquals("age:I", f.toString()); + } + } + @Test + public void testMethods(){ + + List<Method> methods = clzFile.getMethods(); + ConstantPool pool = clzFile.getConstantPool(); + + { + Method m = methods.get(0); + assertMethodEquals(pool,m, + "<init>", + "(Ljava/lang/String;I)V", + "2ab7000c2a2bb5000f2a1cb50011b1"); + + } + { + Method m = methods.get(1); + assertMethodEquals(pool,m, + "setName", + "(Ljava/lang/String;)V", + "2a2bb5000fb1"); + + } + { + Method m = methods.get(2); + assertMethodEquals(pool,m, + "setAge", + "(I)V", + "2a1bb50011b1"); + } + { + Method m = methods.get(3); + assertMethodEquals(pool,m, + "sayHello", + "()V", + "b2001c1222b60024b1"); + + } + { + Method m = methods.get(4); + assertMethodEquals(pool,m, + "main", + "([Ljava/lang/String;)V", + "bb000159122b101db7002d4c2bb6002fb1"); + } + } + + private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ + String methodName = pool.getUTF8String(m.getNameIndex()); + String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); + String code = m.getCodeAttr().getCode(); + Assert.assertEquals(expectedName, methodName); + Assert.assertEquals(expectedDesc, methodDesc); + Assert.assertEquals(expectedCode, code); + } + } 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<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(); + } +}