diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" index 8dbfe95dda..0b256f8f4a 100644 --- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" +++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" @@ -2,4 +2,12 @@ public class ConnectionException extends Exception { + /** + * 自定义异常错误 + * @param string + */ + public ConnectionException(String string) { + + } + } diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" index 4cd0b3eab1..ee55a8cec0 100644 --- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" +++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" @@ -1,5 +1,6 @@ package com.coderising.download.api; public interface DownloadListener { + public void notifyFinished(); } diff --git a/group04/1020483199/1020483199Learning/.classpath b/group04/1020483199/1020483199Learning/.classpath index 3e0fb272a8..04cc82dc42 100644 --- a/group04/1020483199/1020483199Learning/.classpath +++ b/group04/1020483199/1020483199Learning/.classpath @@ -1,7 +1,7 @@ - + diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..ba70c84329 --- /dev/null +++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,92 @@ +package com.coderising.jvm.loader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + /** + * class文件存储位置 + */ + String location = clzPaths.get(0); + File file = new File(location); + File[] files = file.listFiles(); + InputStream in = null; + byte[] bt = null; + + int size = 0; + for(File fileSon:files){ + /** + * 判断出为class文件时 + */ + if(fileSon.isFile() && fileSon.getName().endsWith("EmployeeV1.class")){ + try { + long length = fileSon.length(); + bt = new byte[(int) length]; + byte[] context = new byte[1024]; + in = new FileInputStream(fileSon); + int tempbyte; + while((tempbyte = in.read(context)) != -1){ + for(int i = 0;i < context.length;i++){ + System.arraycopy(context, 0, bt, size, tempbyte); + } + size = tempbyte; + } + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + }finally{ + if(in != null){ + try { + in.close(); + } catch (IOException e) { + } + } + } + + } + } + return bt; + } + + + public void addClassPath(String path) { + + clzPaths.add(path); + + } + + + + public String getClassPath(){ + StringBuilder sb = new StringBuilder(); + for(int i = 0;i < clzPaths.size();i++){ + if(i == clzPaths.size() - 1){ + sb.append(clzPaths.get(i)); + break; + } + sb.append(clzPaths.get(i)).append(";"); + + } + return sb.toString(); + } + + + + + +} diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..7c7d1bb15a --- /dev/null +++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,91 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + static String path1 = "F:/myGithub/coding2017/group04/1020483199/FourthHomeWork/bin/com/coderising/jvm/test"; + static String path2 = "C:/temp"; + + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + + loader.addClassPath(path1); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > x > 5 > 4 > 5插入之后 + public void add(int index , Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p.next != null){ + k++; + p = p.next;//当前p为要插入位置的前一个节点 + } + + if(p != null){ + Node nd = new Node(o); + nd.next = p.next; + p.next = nd; + } + + size++; + + } + } + public Object get(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + Node p = head; + int k = 0; + while(k < index && p.next !=null){ + k++; + p = p.next; + } + return p.data; + } + //3 > 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > 4 > 5插入之后 + public Object remove(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + if(head == null){ + return null; + } + if(index == 0){ + head = head.next; + size--; + return head.data; + }else{ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p != null){ + k++; + p = p.next; + } + Node pn = p.next; + if(pn != null){ + p.next = pn.next; + size--; + return pn.data; + } + + } + } + return null; + } + + public int size(){ + + return size; + } + + public void addFirst(Object o){ + if(head != null){ + Node nd = new Node(o); + Node first = head; + head = nd; + first = nd.next; + } + } + public void addLast(Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(p.next != null && k < size - 1){ + p = p.next; + k++; + } + Node newNode = new Node(o); + p.next = newNode; + } + } + public Object removeFirst(){ + Node node = head; + if(head != null){ + head = head.next; + } + return node.data; + } + public Object removeLast(){ + Node p = head; + int k = 0; + while(p.next != null && k < size - 2){ + k++; + p = p.next; + } + + p.next = null; + return p.next; + } + public Iterator iterator(){ + return null; + } + + + private static class Node{ + Object data; + Node next; + + private Node(Object o){ + this.data = o; + this.next = null; + } + } + + /** + * 把该链表逆置 + * head head + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + /** + * 长度超过1的单链表需要逆转 + */ + if(head == null || head.next == null){ + return; + } + Stack st = new Stack(); + Node currentNode = head; + while(currentNode != null){ + st.push(currentNode); + Node nextNode = currentNode.next; + currentNode.next = null;//断开连接 + currentNode = nextNode; + } + + head = (Node) st.pop(); + currentNode = head; + while(!st.isEmpty()){ + Node nextNode = (Node) st.pop(); + currentNode.next = nextNode; + currentNode = nextNode; + } + } + + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int num = size / 2; + for(int i = 0; i < num; i++){ + removeFirst(); + } + } + + /** + * 从第i个元素开始,删除length个元素 ,注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i < 0 || i >= size){ + throw new IndexOutOfBoundsException(); + } + int len = size - i >= length ? length : size - i; + int k = 0; + while(k < len){ + remove(i); + k++; + } + + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] newList = new int[list.size()]; + for(int i = 0;i < list.size(); i++){ + newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString()); + } + return newList; + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + for(int j = 0;j < list.size();j++){ + this.remove(list.get(j)); + } + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(head == null){ + throw new RuntimeException("LinkedList is null"); + + } + Node currentNode = head; + Node preNode = head; + while(currentNode.next != null){ + currentNode = currentNode.next; + Object data = preNode.data; + while(currentNode.data == data){ + if(currentNode.next == null){ + preNode.next = null; + break; + } + preNode.next = currentNode.next; + size--; + currentNode = currentNode.next; + if(currentNode == null){ + break; + } + } + preNode = preNode.next; + } + } + /** + * 传入删除数据节点 + */ + public void remove(Object obj){ + if(head == null){ + throw new RuntimeException("linkedlist is nuull"); + + } + if(head.data.equals(obj)){ + head = head.next; + size--; + }else{ + Node pre = head; + Node currentNode = head.next; + while(currentNode != null){ + if(currentNode.data.equals(obj)){ + pre.next = currentNode.next; + size--; + } + pre = pre.next; + currentNode = currentNode.next; + } + } + } + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + Node node = head; + int start = -1; + int end = -1; + int i = 0; + while(node != null){ + if((Integer)node.data <= min){ + start = i; + } + if((Integer)node.data >= max){ + end = i; + break; + } + node = node.next; + i++; + } + if(start == -1){ + start = 0; + } + if(end == -1){ + end = size; + } + this.remove(start+1, end-start-1); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(list == null){ + return null; + } + + LinkedList newList = new LinkedList(); + int fi = 0; + int se = 0; + while(fi < this.size && se < list.size()){ + int val1 = (Integer) this.get(fi); + int val2 = (Integer) list.get(se); + if(val1 == val2){ + newList.add(val1); + fi++; + se++; + }else if(val1 < val2){ + fi++; + }else{ + se++; + } + + } + return newList; + } + + public static void main(String[] args) { + LinkedList linkedList = new LinkedList(); + linkedList.add(11); + linkedList.add(22); + linkedList.add(33); + linkedList.add(44); + linkedList.add(55); + linkedList.reverse(); + for(int i = 0; i < linkedList.size; i++){ + System.out.println(linkedList.get(i)); + } + } +} diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java new file mode 100644 index 0000000000..55ff205b5d --- /dev/null +++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java @@ -0,0 +1,9 @@ +package com.coding.basic.linkedList; + +public interface List { + public void add(Object o); + public void add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..e5ddb476a6 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,96 @@ +package com.coderising.array; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public void reverseArray(int[] origin){ + + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray){ + return null; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2){ + return null; + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public int[] grow(int [] oldArray, int size){ + return null; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public int[] fibonacci(int max){ + return null; + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + return null; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + return null; + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator){ + return null; + } + + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..d16eca2319 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,42 @@ +package com.coderising.download; + + + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + + private Connection conn; + private int startPos; + private int endPos; + private String filePath; + private CyclicBarrier barrier; + + public DownloadThread(Connection conn, int startPos, int endPos,String filePath,CyclicBarrier barrier){ + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.filePath = filePath; + this.barrier = barrier; + } + public void run(){ + try { + System.out.println("线程" + this.getName() + "开始下载. startPos:" + startPos + "; endPos:" + endPos); + byte[] buffer = conn.read(startPos, endPos); + RandomAccessFile ra = new RandomAccessFile(filePath, "rw"); + ra.seek(startPos); + ra.write(buffer); + //关闭流 + ra.close(); + conn.close(); + barrier.await(); + System.out.println("线程" + this.getName() + "下载完成."); + }catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..c6cdf3fc4a --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,139 @@ +package com.coderising.download; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CyclicBarrier; + +import org.junit.internal.runners.statements.RunAfters; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + + +public class FileDownloader { + + private String url; + + private String localFile; + + DownloadListener listener; + + ConnectionManager cm; + + private final static int thread_count = 3; + + public FileDownloader(String _url,String localFile) { + this.url = _url; + this.localFile = localFile; + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接, + //通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, + //调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, + //这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, + //然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, + //返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + CyclicBarrier barrier = new CyclicBarrier(thread_count, new Runnable() { + + @Override + public void run() { + listener.notifyFinished(); + } + }); + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + createPlaceHolderFile(this.localFile,length); + + int[] [] ranges = allowcateDownloadRange(thread_count,length); + + for(int i = 0; i < thread_count; i++){ + + DownloadThread thread= new DownloadThread(conn, ranges[i][0], ranges[i][1], localFile, barrier); + + thread.start(); + + } + + } catch (Exception e) { + e.printStackTrace(); + + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + private int[][] allowcateDownloadRange(int threadCount, int length) { + int[][] ranges = new int[thread_count][2]; + + int eachThreadSize = length / threadCount; + + int left = length % threadCount; + + for(int i = 0 ; i < thread_count;i++){ + int startPos = i * eachThreadSize; + + int endPos = (i+1) * eachThreadSize - 1; + + if((i==thread_count -1)){ + endPos += left; + } + + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + + return ranges; + } + + private void createPlaceHolderFile(String localfile, int length) throws IOException { + RandomAccessFile file = new RandomAccessFile(localfile, "rw"); + for(int i = 0;i < length ; i++){ + file.write(0); + } + file.close(); + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..7393f57040 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,90 @@ +package com.coderising.download; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testContentLength() throws Exception{ + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + Assert.assertEquals(35470, conn.getContentLength()); + } + + @Test + public void testRead() throws Exception{ + + ConnectionManager connMan = new ConnectionManagerImpl(); + Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"); + + byte[] data = conn.read(0, 35469); + + Assert.assertEquals(35470, data.length); + + data = conn.read(0, 1023); + + Assert.assertEquals(1024, data.length); + + data = conn.read(1024, 2023); + + Assert.assertEquals(1000, data.length); + + + // 测试不充分,没有断言内容是否正确 + } + + @Test + public void testDownload() { + + String url = "http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg"; + + FileDownloader downloader = new FileDownloader(url, "F:/picture/a.png"); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..105f00f03a --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,13 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + /** + * 自定义异常错误 + * @param string + */ + public ConnectionException(Exception e) { + super(e); + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..7b51663ff9 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,6 @@ +package com.coderising.download.api; + +public interface DownloadListener { + + public void notifyFinished(); +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..dcaf5883fa --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,89 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; + +class ConnectionImpl implements Connection { + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException{ + try { + url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + + HttpURLConnection httpConn = (HttpURLConnection)url.openConnection(); + + httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + + endPos); + + InputStream is = httpConn.getInputStream(); + + //is.skip(startPos); + + byte[] buff = new byte[BUFFER_SIZE]; + + int totalLen = endPos - startPos + 1; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + while(baos.size() < totalLen){ + + int len = is.read(buff); + if (len < 0) { + break; + } + baos.write(buff,0, len); + } + + + if(baos.size() > totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + + URLConnection con; + try { + con = url.openConnection(); + + return con.getContentLength(); + + } catch (IOException e) { + e.printStackTrace(); + } + + return -1; + + + } + + @Override + public void close() { + + + } + +} \ No newline at end of file diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..3af9b21485 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,17 @@ +package com.coderising.download.impl; + +import java.net.MalformedURLException; +import java.net.URL; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java new file mode 100644 index 0000000000..dcdbe226ed --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package com.coderising.litestruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java new file mode 100644 index 0000000000..6df190d484 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java @@ -0,0 +1,37 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + + public static View runAction(String actionName, Map parameters) { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + return null; + } + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,43 @@ +package com.coderising.litestruts; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..3fe0a702d4 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java @@ -0,0 +1,27 @@ +package com.coderising.litestruts; + +import java.util.Map; + +public class View { + private String jsp; + + private Map parameters; + + public String getJsp() { + return jsp; + } + + public void setJsp(String jsp) { + this.jsp = jsp; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java new file mode 100644 index 0000000000..1f185736f9 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData = new Object[100]; + + public void add(Object o){ + + } + public void add(int index, Object o){ + + } + + public Object get(int index){ + return null; + } + + public Object remove(int index){ + return null; + } + + public int size(){ + return -1; + } + + public Iterator iterator(){ + return null; + } + +} diff --git a/group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java similarity index 100% rename from group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java diff --git a/group04/120549547/base/src/com/coding/basic/Iterator.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java similarity index 100% rename from group04/120549547/base/src/com/coding/basic/Iterator.java rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..7b10ffb8b6 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java @@ -0,0 +1,374 @@ +package com.coding.basic; + +import java.util.Stack; + +public class LinkedList implements List { + private int size; + + private Node head; + + public LinkedList(){ + size = 0; + + head = null; + } + + public void add(Object o){ + Node nd = new Node(o); + if(head == null){ + head = nd; + }else{ + Node p = head; + while(p.next != null){ + p = p.next; + } + p.next = nd; + } + size ++; + + } + //3 > 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > x > 5 > 4 > 5插入之后 + public void add(int index , Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p.next != null){ + k++; + p = p.next;//当前p为要插入位置的前一个节点 + } + + if(p != null){ + Node nd = new Node(o); + nd.next = p.next; + p.next = nd; + } + + size++; + + } + } + public Object get(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + Node p = head; + int k = 0; + while(k < index && p.next !=null){ + k++; + p = p.next; + } + return p.data; + } + //3 > 2 > 1 > 5 > 4 > 5改变之前 + //0 1 2 3 4 5index + //3 > 2 > 1 > 4 > 5插入之后 + public Object remove(int index){ + if(index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + if(head == null){ + return null; + } + if(index == 0){ + head = head.next; + size--; + return head.data; + }else{ + if(head != null){ + int k = 0; + Node p = head; + while(k < index - 1 && p != null){ + k++; + p = p.next; + } + Node pn = p.next; + if(pn != null){ + p.next = pn.next; + size--; + return pn.data; + } + + } + } + return null; + } + + public int size(){ + + return size; + } + + public void addFirst(Object o){ + if(head != null){ + Node nd = new Node(o); + Node first = head; + head = nd; + first = nd.next; + } + } + public void addLast(Object o){ + if(head != null){ + int k = 0; + Node p = head; + while(p.next != null && k < size - 1){ + p = p.next; + k++; + } + Node newNode = new Node(o); + p.next = newNode; + } + } + public Object removeFirst(){ + Node node = head; + if(head != null){ + head = head.next; + } + return node.data; + } + public Object removeLast(){ + Node p = head; + int k = 0; + while(p.next != null && k < size - 2){ + k++; + p = p.next; + } + + p.next = null; + return p.next; + } + public Iterator iterator(){ + return null; + } + + + private static class Node{ + Object data; + Node next; + + private Node(Object o){ + this.data = o; + this.next = null; + } + } + + /** + * 把该链表逆置 + * head head + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + /** + * 长度超过1的单链表需要逆转 + */ + if(head == null || head.next == null){ + return; + } + Stack st = new Stack(); + Node currentNode = head; + while(currentNode != null){ + st.push(currentNode); + Node nextNode = currentNode.next; + currentNode.next = null;//断开连接 + currentNode = nextNode; + } + + head = (Node) st.pop(); + currentNode = head; + while(!st.isEmpty()){ + Node nextNode = (Node) st.pop(); + currentNode.next = nextNode; + currentNode = nextNode; + } + } + + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int num = size / 2; + for(int i = 0; i < num; i++){ + removeFirst(); + } + } + + /** + * 从第i个元素开始,删除length个元素 ,注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + if(i < 0 || i >= size){ + throw new IndexOutOfBoundsException(); + } + int len = size - i >= length ? length : size - i; + int k = 0; + while(k < len){ + remove(i); + k++; + } + + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + int[] newList = new int[list.size()]; + for(int i = 0;i < list.size(); i++){ + newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString()); + } + return newList; + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + for(int j = 0;j < list.size();j++){ + this.remove(list.get(j)); + } + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(head == null){ + throw new RuntimeException("LinkedList is null"); + + } + Node currentNode = head; + Node preNode = head; + while(currentNode.next != null){ + currentNode = currentNode.next; + Object data = preNode.data; + while(currentNode.data == data){ + if(currentNode.next == null){ + preNode.next = null; + break; + } + preNode.next = currentNode.next; + size--; + currentNode = currentNode.next; + if(currentNode == null){ + break; + } + } + preNode = preNode.next; + } + } + /** + * 传入删除数据节点 + */ + public void remove(Object obj){ + if(head == null){ + throw new RuntimeException("linkedlist is nuull"); + + } + if(head.data.equals(obj)){ + head = head.next; + size--; + }else{ + Node pre = head; + Node currentNode = head.next; + while(currentNode != null){ + if(currentNode.data.equals(obj)){ + pre.next = currentNode.next; + size--; + } + pre = pre.next; + currentNode = currentNode.next; + } + } + } + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + Node node = head; + int start = -1; + int end = -1; + int i = 0; + while(node != null){ + if((Integer)node.data <= min){ + start = i; + } + if((Integer)node.data >= max){ + end = i; + break; + } + node = node.next; + i++; + } + if(start == -1){ + start = 0; + } + if(end == -1){ + end = size; + } + this.remove(start+1, end-start-1); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(list == null){ + return null; + } + + LinkedList newList = new LinkedList(); + int fi = 0; + int se = 0; + while(fi < this.size && se < list.size()){ + int val1 = (Integer) this.get(fi); + int val2 = (Integer) list.get(se); + if(val1 == val2){ + newList.add(val1); + fi++; + se++; + }else if(val1 < val2){ + fi++; + }else{ + se++; + } + + } + return newList; + } + + public static void main(String[] args) { + LinkedList linkedList = new LinkedList(); + linkedList.add(11); + linkedList.add(22); + linkedList.add(33); + linkedList.add(44); + linkedList.add(55); + linkedList.reverse(); + for(int i = 0; i < linkedList.size; i++){ + System.out.println(linkedList.get(i)); + } + } +} diff --git a/group12/446031103/src/com/coding/basic/List.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java similarity index 100% rename from group12/446031103/src/com/coding/basic/List.java rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java new file mode 100644 index 0000000000..36e516e266 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java @@ -0,0 +1,19 @@ +package com.coding.basic; + +public class Queue { + + public void enQueue(Object o){ + } + + public Object deQueue(){ + return null; + } + + public boolean isEmpty(){ + return false; + } + + public int size(){ + return -1; + } +} diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java new file mode 100644 index 0000000000..a25d5b8024 --- /dev/null +++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java @@ -0,0 +1,22 @@ +package com.coding.basic; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + } + + public Object pop(){ + return null; + } + + public Object peek(){ + return null; + } + public boolean isEmpty(){ + return false; + } + public int size(){ + return -1; + } +} diff --git a/group04/120549547/base/buil.bat b/group04/120549547/base/buil.bat deleted file mode 100644 index 7164a42ac0..0000000000 --- a/group04/120549547/base/buil.bat +++ /dev/null @@ -1,5 +0,0 @@ -javac -sourcepath src -d classes -encoding utf-8 src\com\coding\basic\*.java - -java -cp classes com.coding.basic.Main - -pause \ No newline at end of file diff --git a/group04/120549547/base/src/com/coding/basic/ArrayList.java b/group04/120549547/base/src/com/coding/basic/ArrayList.java deleted file mode 100644 index 56e7aa4c26..0000000000 --- a/group04/120549547/base/src/com/coding/basic/ArrayList.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.coding.basic; -import java.util.Arrays; - -public class ArrayList implements List { - /*默认数组容量*/ - public static final int DEFAULT_CAPCATITY = 10; - - /*数组元素个数*/ - private int size; - - private Object[] elementData; - - public ArrayList(){ - this(DEFAULT_CAPCATITY); - } - - public ArrayList(int capacity){ - if (capacity<0 || capacity>Integer.MAX_VALUE) - throw new IllegalArgumentException("非法容量: " + capacity); - elementData = new Object[capacity]; - } - - - public void add(Object o){ - /*判断是否需要扩容*/ - ensureCapacity(size + 1); - elementData[size++] = o; - } - - public void add(int index, Object o){ - checkIndex(index); - /*判断是否需要扩容*/ - ensureCapacity(size + 1); - /*将index->size的元素依次向右移一个位置*/ - System.arraycopy(elementData, index, elementData, index+1, size-index); - /*插入o的值*/ - elementData[index] = o; - size++; - } - - - public Object get(int index){ - - checkIndex(index); - return elementData[index]; - } - - public Object remove(int index){ - - checkIndex(index); - Object value = elementData[index]; - /*将index+1 -> size的元素依次向左移一个位置*/ - System.arraycopy(elementData,index+1, elementData, index, size-index-1); - elementData[--size]=null; //释放最后一个元素,同时size减一; - return value; - } - - public int size(){ - return this.size; - } - - public Iterator iterator(){ - return null; - } - /* 确认容量是否足够,也可以直接调用手动扩容*/ - public void ensureCapacity(int minCapacity){ - int oldCapacity = elementData.length; - /*容量不足需要扩容*/ - if(oldCapacity < minCapacity){ - int newCapacity = oldCapacity * 2; //扩大2倍 - if (newCapacity < minCapacity){ - newCapacity = minCapacity; //扩容后仍不足,取最大值 - } - System.out.println("数据扩容至: " + newCapacity); - elementData = Arrays.copyOf(elementData, newCapacity); - } - - } - - private void checkIndex(int index){ - if (index<0 || index>= size) - throw new IndexOutOfBoundsException ("index非法: " + index); - } - @Override - public String toString(){ - - StringBuffer sb = new StringBuffer(""); - for(int i=0; i "); - } - return sb.toString(); - } -} diff --git a/group04/120549547/base/src/com/coding/basic/LinkedList.java b/group04/120549547/base/src/com/coding/basic/LinkedList.java deleted file mode 100644 index edfbcc1007..0000000000 --- a/group04/120549547/base/src/com/coding/basic/LinkedList.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.coding.basic; - -public class LinkedList implements List { - - private Node head; - private int size; - /*创建一个带头节点的单链表*/ - public LinkedList(){ - head = new Node(null); - } - - /*添加一个元素(尾插法)*/ - public void add(Object o){ - - Node node = new Node(o); - Node pos = head; - //找到最后一个元素位置 - while(pos.next != null){ - pos = pos.next; - } - pos.next = node; - size++; - - } - - /*在index位置插入*/ - public void add(int index , Object o){ - //判断索引是否合法 - checkIndex(index); - Node node = new Node(o); - Node pos = head; - //找到插入位置 - while(index-- != 0){ - pos = pos.next; - } - node.next = pos.next; - pos.next = node; - size++; - - } - public Object get(int index){ - checkIndex(index); - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - Node pos = head.next; //pos指向要获取的节点 - while(index-- !=0){ - pos = pos.next; - } - - return pos.data; - } - public Object remove(int index){ - checkIndex(index); - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - - Node pos = head; //pos指向要删除的前一个结点 - while(index-- != 0){ - pos = pos.next; - } - Node value = pos.next; //要删除的节点 - pos.next = value.next; - size--; - return value.data; - - - } - - public int size(){ - return size; - } - - public void addFirst(Object o){ - - } - public void addLast(Object o){ - this.add(o); - } - public Object removeFirst(){ - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - return remove(0); - } - public Object removeLast(){ - if(this.isEmpty()){ - throw new IllegalArgumentException ("链表为空"); - } - return remove(size-1); - } - - public boolean isEmpty(){ - return size == 0; - } - public Iterator iterator(){ - return null; - } - - private void checkIndex(int index){ - if (index<0 || index>=size ){ - throw new IllegalArgumentException ("index不合法: " + index ); - } - } - - @Override - public String toString(){ - - StringBuffer sb = new StringBuffer(""); - for(int i=0; i "); - } - return sb.toString(); - } - - private static class Node{ - public Object data; - public Node next; - - public Node(Object data){ - this.data = data; - this.next = null; - } - - } -} diff --git a/group04/120549547/base/src/com/coding/basic/Main.java b/group04/120549547/base/src/com/coding/basic/Main.java deleted file mode 100644 index de8a0b0990..0000000000 --- a/group04/120549547/base/src/com/coding/basic/Main.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.coding.basic; -import com.coding.basic.*; - -class Main{ - - public static void main(String[] args){ - System.out.println("数组测试开始"); - ArrayListTest(); - System.out.println("----------------分割线----------------"); - System.out.println("链表测试开始"); - LinkedListTest(); - System.out.println("----------------分割线----------------"); - System.out.println("栈测试开始"); - StatckTest(); - System.out.println("----------------分割线----------------"); - System.out.println("队测试开始"); - QueueTest(); - } - - public static void ArrayListTest(){ - ArrayList list = new ArrayList(2); - list.add("HelloBobi0"); - list.add("HelloBobi1"); - list.add("HelloBobi2"); - list.add("HelloBobi3"); - list.add("HelloBobi4"); - list.add("HelloBobi5"); - System.out.println((String)list.get(0)); - System.out.println((String)list.get(4)); - list.add(3, "Hei Man"); - list.remove(5); - System.out.println(list); - System.out.println("size:=" + list.size()); - } - - public static void LinkedListTest(){ - LinkedList ll = new LinkedList(); - - - ll.add("SingleDog0"); - ll.add("SingleDog1"); - ll.add("SingleDog2"); - ll.add("SingleDog3"); - ll.add("SingleDog4"); - ll.add("SingleDog5"); - - System.out.println((String)(ll.get(1))); - System.out.println(ll); - System.out.println("size:=" + ll.size()); - ll.remove(0); - ll.removeFirst(); - ll.removeLast(); - System.out.println(ll); - } - - public static void StatckTest(){ - Stack stack = new Stack(); - stack.push("虾师傅0"); - stack.push("虾师傅1"); - stack.push("虾师傅2"); - stack.push("虾师傅3"); - stack.push("虾师傅4"); - - stack.pop(); - System.out.println(stack.peek()); - System.out.println(stack); - - } - public static void QueueTest(){ - Queue queue = new Queue(); - queue.enQueue("龙师傅0"); - queue.enQueue("龙师傅1"); - queue.enQueue("龙师傅2"); - queue.enQueue("龙师傅3"); - queue.enQueue("龙师傅4"); - - System.out.println(queue.deQueue()); - System.out.println(queue.deQueue()); - System.out.println(queue.deQueue()); - System.out.println(queue.deQueue()); - System.out.println(queue.size()); - - - } -} \ No newline at end of file diff --git a/group04/120549547/base/src/com/coding/basic/Queue.java b/group04/120549547/base/src/com/coding/basic/Queue.java deleted file mode 100644 index 8f86f7492c..0000000000 --- a/group04/120549547/base/src/com/coding/basic/Queue.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.coding.basic; -import com.coding.basic.*; -public class Queue { - private LinkedList list; - - public Queue(){ - list = new LinkedList(); - } - /*入队*/ - public void enQueue(Object o){ - list.addLast(o); - } - - /*出队*/ - public Object deQueue(){ - if (isEmpty()){ - System.out.println("队空"); - } - return list.removeFirst(); - } - - public boolean isEmpty(){ - return list.isEmpty(); - } - - public int size(){ - return list.size(); - } -} diff --git a/group04/120549547/base/src/com/coding/basic/Stack.java b/group04/120549547/base/src/com/coding/basic/Stack.java deleted file mode 100644 index f7d3bba3db..0000000000 --- a/group04/120549547/base/src/com/coding/basic/Stack.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.coding.basic; -import com.coding.basic.LinkedList; - -public class Stack { - private LinkedList list; - - public Stack(){ - list = new LinkedList(); - } - - public void push(Object o){ - list.addLast(o); - } - - public Object pop(){ - if(isEmpty()){ - System.out.println("栈空"); - } - return list.removeLast(); - - } - - public Object peek(){ - return list.get(list.size()-1); - } - public boolean isEmpty(){ - return list.isEmpty(); - } - public int size(){ - return list.size(); - } - - @Override - public String toString(){ - return list.toString(); - } -} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java new file mode 100644 index 0000000000..d7ac820192 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java @@ -0,0 +1,32 @@ +package com.coding.basic; + +public class BinaryTreeNode { + + private Object data; + private BinaryTreeNode left; + private BinaryTreeNode right; + + public Object getData() { + return data; + } + public void setData(Object data) { + this.data = data; + } + public BinaryTreeNode getLeft() { + return left; + } + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + public BinaryTreeNode getRight() { + return right; + } + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(Object o){ + return null; + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..31d6470bef --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java @@ -0,0 +1,8 @@ +package com.coding.basic; + +public interface Iterator { + boolean hasNext(); + + T next(); + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/List.java b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java new file mode 100644 index 0000000000..70a783968e --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java @@ -0,0 +1,31 @@ +package com.coding.basic; + +public interface List{ + int size(); + + boolean isEmpty(); + + boolean contains(Object o); + + Object[] toArray(); + + boolean add(T o); + + boolean remove(T o); + + void clear(); + + T get(int index); + + T set(int index, T o); + + void add(int index, T o); + + T remove(int index); + + int indexOf(T o); + + Iterator iterator(); + + void printf(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java new file mode 100644 index 0000000000..459ec560b4 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java @@ -0,0 +1,24 @@ +package com.coding.basic; + +import com.coding.basic.array.ArrayList; + +public class Stack { + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + } + + public Object pop(){ + return null; + } + + public Object peek(){ + return null; + } + public boolean isEmpty(){ + return false; + } + public int size(){ + return -1; + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java new file mode 100644 index 0000000000..6c392a3618 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java @@ -0,0 +1,155 @@ +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +import java.util.Objects; + +public class ArrayList implements List { + + private int size; + private Object[] dataArray = new Object[0]; + + public int size() { + return this.size; + } + + public boolean isEmpty() { + return this.size == 0; + } + + public boolean contains(Object o) { + for (Object obj : dataArray) { + if (Objects.equals(obj, o)){ + return true; + } + } + return false; + } + + public Object[] toArray() { + Object[] array = new Object[size]; + System.arraycopy(dataArray, 0, array, 0, size); + return array; + } + + public boolean add(T o) { + ensureCapacity(size+1); + dataArray[size] = o; + size++; + return true; + } + + + + public boolean remove(T o) { + int index = indexOf(o); + if (index < 0){ + return false; + } + + System.arraycopy(dataArray, index + 1, dataArray, index, size - 1 - index); + dataArray[size - 1] = null; + size--; + return true; + } + + public void clear() { + for (int i = 0; i < size; i++) { + dataArray[i] = null; + } + size = 0; + } + @SuppressWarnings("unchecked") + public T get(int index) { + if (index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + + return (T) dataArray[index]; + } + + public T set(int index, T o) { + if (index < 0 || index >= size){ + throw new IndexOutOfBoundsException(); + } + dataArray[index] = o; + return o; + } + + public void add(int index, T o) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException(); + } + ensureCapacity(size + 1); + System.arraycopy(dataArray, index, dataArray, index + 1, size - index); + + dataArray[index] = o; + + size++; + } + + public T remove(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + T removeData = (T) dataArray[index]; + System.arraycopy(dataArray, index + 1, dataArray, index, size - index -1 ); + dataArray[size - 1] = null; + size--; + return removeData; + } + + public int indexOf(T o) { + for (int i = 0; i < size; i++) { + if (Objects.equals(o, dataArray[i])){ + return i; + } + } + return -1; + } + + public Iterator iterator() { + return new ArrayListIterator(); + } + + @Override + public void printf() { + for (int i = 0; i < size; i++) { + if (i == size - 1){ + System.out.print(dataArray[i]); + }else { + System.out.print(dataArray[i] + "->"); + } + } + } + + private void ensureCapacity(int minCapacity) { + if (minCapacity > dataArray.length){ + int newCapacity = Math.max(minCapacity, dataArray.length * 2); + Object[] newDataArray = new Object[newCapacity]; + System.arraycopy(dataArray, 0, newDataArray, 0, dataArray.length); + dataArray = newDataArray; + } + + } + + + private class ArrayListIterator implements Iterator { + + private int pos; + + @Override + public boolean hasNext() { + return pos < size(); + } + + @Override + public T next() { + if (hasNext()){ + return get(pos++); + } + return null; + } + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java new file mode 100644 index 0000000000..411b60990b --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java @@ -0,0 +1,269 @@ +package com.coding.basic.array; + +import java.util.Arrays; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public static void reverseArray(int[] origin){ + + if (origin == null || origin.length == 0){ + return; + } + + int temp ; + for (int i = 0; i < (origin.length / 2); i++) { + temp = origin[i]; + origin[i] = origin[(origin.length - 1) - i]; + origin[(origin.length - 1)- i] = temp; + } + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public static int[] removeZero(int[] oldArray){ + if (oldArray == null ){ + return null; + } + + if (oldArray.length == 0){ + return oldArray; + } + + int count = 0; + int[] temp = new int[oldArray.length]; + + for (int i = 0; i < oldArray.length; i++) { + if (oldArray[i] != 0){ + temp[count++] = oldArray[i]; + } + } + + int[] result = new int[count]; + + System.arraycopy(temp, 0, result, 0, count); + return result; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public static int[] merge(int[] array1, int[] array2){ + if (array1 == null && array2 == null){ + return null; + } + + if (array1 == null){ + return array2; + } + + if (array2 == null){ + return array1; + } + + int length1 = array1.length; + int length2 = array2.length; + int[] temp = new int[length1 + length2]; + int i,j,k; + for ( i = 0, j = 0, k = 0; i < length1 && j < length2 ;) { + + if (array1[i] < array2[j]){ + temp[k++] = array1[i++]; + }else if (array1[i] > array2[j]){ + temp[k++] = array2[j++]; + }else { + temp[k++] = array1[i]; + i++; + j++; + } + } + + while (i < length1){ + temp[k++] = array1[i++]; + } + + while (j < length2){ + temp[k++] = array2[j++]; + } + int[] result = new int[k]; + System.arraycopy(temp, 0, result, 0, k); + return result; + + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public static int[] grow(int [] oldArray, int size){ + + int oldSize = oldArray.length; + int[] newArray = new int[oldSize + size]; + + System.arraycopy(oldArray, 0, newArray, 0, oldSize); + + return newArray; + } + + /** + * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 + * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] + * max = 1, 则返回空数组 [] + * @param max + * @return + */ + public static int[] fibonacci1(int max){ + if (max == 1){ + return new int[0]; + } + + int[] temp = new int[max]; + int count = 0; +// for (int i = 1; i < max; i++) { +// int num = fibonacci(i); +// if (num < max){ +// temp[count++] = num; +// }else { +// break; +// } +// } + temp[0] = 1; + temp[1] = 2; + for (int i = 2; i < max; i++) { + temp[i] = temp[i-1] + temp[i-2]; //直接在数组中实现斐波那契数列 + if (temp[i] >= max){ + break; + }else { + count++; + } + } + + + + return Arrays.copyOf(temp, count); + } + + private static int fibonacci(int n){ + if (n <= 0){ + throw new IllegalArgumentException(); + } + + if (n == 1 || n == 2) { + return 1; + } + + return fibonacci(n - 1) + fibonacci(n - 2); + + } + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public static int[] getPrimes(int max){ + + if (max <= 2){ + return new int[0]; + } + + int[] temp = new int[max]; + + int count = 0; + for (int i = 2; i < max; i++) { + int j; + for ( j = 2; j * j < i; j++) { + if (i % j == 0){ + break; + } + } + + if (j * j >= i){ + temp[count++] = i; + } + } + + return Arrays.copyOf(temp, count); + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public static int[] getPerfectNumbers(int max){ + if ( max <= 1){ + return new int[0]; + } + + ArrayList array = new ArrayList<>(); + for (int i = 2; i < max; i++) { + int sum = 0; //存储因子和 + for (int j = 1; j < i; j++) { + if (i % j == 0){ + sum += j; + } + } + + if (sum == i){ + array.add(i); + } + } + int[] result = new int[array.size()]; + + for (int i = 0; i < array.size(); i++) { + result[i] = array.get(i); + } + return result; + + + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public static String join(int[] array, String seperator){ + + if (array == null || array.length == 0){ + return null; + } + + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < array.length-1; i++) { + sb.append(array[i]).append(seperator); + } + + sb.append(array[array.length-1]); + + return sb.toString(); + } + + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..a4f2c14606 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,60 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node() { + } + } + + private int capacity; + + + private Node first;// 链表头 + private Node last;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + + + } + + + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..67cf36067b --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java new file mode 100644 index 0000000000..eb128c4b24 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java @@ -0,0 +1,369 @@ +package com.coding.basic.linklist; + +import com.coding.basic.Iterator; +import com.coding.basic.List; + +import java.util.Objects; + +public class LinkedList implements List { + private int size; + + private Node head; + + private Node last; + + + + private static class Node { + T data; + Node pre; + Node next; + + Node(T data) { + this.data = data; + } + + + } + + public LinkedList(){ + this.head = new Node<>(null); + } + + @Override + public int size() { + return this.size; + } + + @Override + public boolean isEmpty() { + return this.size == 0; + } + + @Override + public boolean contains(Object o) { + Node node = this.head; + while (node.next != null){ + if (Objects.equals(node.data, o)){ + + return true; + } + node = node.next; + } + return false; + } + + @Override + public Object[] toArray() { + Object[] dataArray = new Object[size]; + Node node = head.next; + for (int i = 0; i < size&& node != null; i++, node = node.next) { + dataArray[i] = node.data; + + } + return dataArray; + } + + @Override + public boolean add(T o) { + if (this.last == null){ + this.last = new Node<>(o); + this.last.pre = this.head; + this.head.next = this.last; + }else { + Node oldLast = this.last; + this.last = new Node<>(o); + this.last.pre = oldLast; + oldLast.next = this.last; + + } + this.size++; + return true; + } + @SuppressWarnings("unchecked") + @Override + public boolean remove(T o) { + + + Node curNode = head.next; + Node preNode; + while (curNode != null){ + preNode = curNode.pre; //指向前一个节点 + + if (Objects.equals(curNode.data, o)){ + removeNode(preNode, curNode); + return true; + } + curNode = curNode.next; + } + + return false; + } + + private void removeNode(Node preNode, Node node) { + + if (this.last == node){ //如果删除的是last节点的情况 + if (preNode == this.head){ //如果只有一个节点的情况 + this.last = null; + }else { + this.last = preNode; + } + }else { + node.next.pre = node.pre; + + } + preNode.next = node.next; + + + + + this.size--; + } + + @Override + @SuppressWarnings("unchecked") + public void clear() { + for (Node x = head; x != null;){ + Node next = x.next; + x.data = null; + x.pre = null; + x.next = null; + x = next; + } + head = last = null; + size = 0; + + } + + @Override + @SuppressWarnings("unchecked") + public T get(int index) { + return (T) getNode(index).data; + } + + + + @Override + public T set(int index, T o) { + Node node = getNode(index); + node.data = o; + return o; + } + + @SuppressWarnings("unchecked") + @Override + public void add(int index, T o) { + ensureIndex(index); + Node newNode = new Node<>(o); + Node curNode = getNode(index); + Node pre = curNode.pre; + + newNode.next = curNode; + newNode.pre = pre; + curNode.pre = newNode; + pre.next = newNode; + + size++; + + } + + @Override + public T remove(int index) { + Node node = getNode(index); + Node pre = node.pre; + if (node == last){ //如果是最后一个节点 + if (pre != head){ //如果是唯一节点 + last = null; + }else { + last = node.pre; + } + } + + pre.next = node.next; + if (node.next != null){ + node.next.pre = pre; + } + size--; + return (T) node.data; + } + + @Override + public int indexOf(T o) { + Node node = head; + int index = 0; + + while (node.next != null){ + node = node.next; + if (Objects.equals(node.data, o)){ + return index; + } + index ++; + } + return index; + } + + @Override + public Iterator iterator() { + return new LinkedListIterator(); + } + + @Override + public void printf() { + Node node = head.next; + while (node != null){ + if (node.next != null) { + System.out.print(node.data + " -> "); + }else { + System.out.print(node.data); + } + node = node.next; + } + System.out.println(); + System.out.println("head = " + head); + System.out.println("last = " + last); + + } + + + private Node getNode(int index) { + ensureIndex(index); + Node node = this.head; + for (int i = 0; i <= index; i++) { + node = node.next; + } + return node; + } + + private void ensureIndex(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if (head.next == null && head.next.next == null){ //如果链表为空或者只有一个元素,不做变换 + return; + } + + last = head.next; + + Node pre = head.next; + Node cur = pre.next; + Node next; + pre.next = null; + while (cur != null){ + next = cur.next; + cur.next = pre; + pre = cur; + cur = next; + } + head.next = pre; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if (isEmpty()){ + return; + } + int halfIndex = size / 2; + + if (halfIndex >= 0){ + head.next = getNode(halfIndex); + } + + size = size - halfIndex; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + ensureIndex(i); + ensureIndex(i + length - 1); + + for (int j = i; j < i + length; j++) { + remove(i); + } + } + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + return null; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + return null; + } + + private class LinkedListIterator implements Iterator { + private Node node; + + LinkedListIterator(){ + node = head; + } + @Override + public boolean hasNext() { + return node.next != null; + } + + @Override + public T next() { + if (hasNext()){ + node = node.next; + return (T) node.data; + } + return null; + } + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java new file mode 100644 index 0000000000..db2047f096 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java @@ -0,0 +1,97 @@ +package com.coding.basic.queue; + +import java.util.NoSuchElementException; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ArrayQueue implements Queue { + + private int size; + private Object[] dataArray; + private int front; + private int rear; + + public ArrayQueue(int Capacity) { + this.dataArray = new Object[Capacity]; + this.front = 0; + this.rear = 0; + this.size = 0; + } + + @Override + public boolean add(T t) { + if (offer(t)){ + return true; + }else { + throw new IllegalStateException(); + } + } + + @Override + public boolean offer(T t) { + if (size >= dataArray.length){ + return false; + } + + dataArray[rear++] = t; + + if (rear == dataArray.length){ + rear = 0; + } + + size++; + return true; + } + + @Override + public T remove() { + T value = poll(); + if (value != null){ + return value; + }else { + throw new NoSuchElementException(); + } + } + + @Override + public T poll() { + if (size == 0){ + return null; + } + + + T value = (T) dataArray[front++]; + if (front == dataArray.length){ + front = 0; + } + + size--; + return value; + + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + + @Override + public T peek() { + if (size == 0){ + return null; + }else { + return (T) dataArray[front]; + } + } + + public void printf() { + for (int i = 0; i < size; i++) { + + System.out.print(dataArray[(front + i) % dataArray.length] + " "); + } + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java new file mode 100644 index 0000000000..64f86616f4 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java @@ -0,0 +1,16 @@ +package com.coding.basic.queue; + +public interface Queue { + + boolean add(T t); + + boolean offer(T t); + + T remove(); + + T poll(); + + boolean isEmpty(); + + T peek(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java new file mode 100644 index 0000000000..9fc2c860d2 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java @@ -0,0 +1,21 @@ +package com.coding.download; + + +import com.coding.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + + public DownloadThread( Connection conn, int startPos, int endPos){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ + + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java new file mode 100644 index 0000000000..ec975a9aae --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java @@ -0,0 +1,73 @@ +package com.coding.download; + + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + new DownloadThread(conn,0,length-1).start(); + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java new file mode 100644 index 0000000000..84fbc8afa2 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.coding.download; + +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; +import com.coding.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://localhost:8080/test.jpg"; + + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java new file mode 100644 index 0000000000..65f3dae9c5 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coding.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java new file mode 100644 index 0000000000..1db8b093ec --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coding.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1d1a83caf2 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coding.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java new file mode 100644 index 0000000000..c41045b0e8 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coding.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..0ddbf36e1b --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java @@ -0,0 +1,28 @@ +package com.coding.download.impl; + +import com.coding.download.api.Connection; + +import java.io.IOException; + + +public class ConnectionImpl implements Connection { + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + return null; + } + + @Override + public int getContentLength() { + + return 0; + } + + @Override + public void close() { + + + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..0f1c658a60 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,16 @@ +package com.coding.download.impl; + + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return null; + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java new file mode 100644 index 0000000000..26799a83a4 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java @@ -0,0 +1,124 @@ +package com.coding.litestruts; + + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class Configuration { + Map actions = new HashMap<>(); + + + + public Configuration(String path) throws IOException { + + URL pathName = Configuration.class.getClassLoader().getResource(path); + + assert pathName != null; +// InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); 默认则是从ClassPath根下获取,path不能以’/'开头 +// InputStream is = this.getClass().getResourceAsStream("/" + path); // path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取 +// InputStream is = pathName.openStream(); + InputStream is = new FileInputStream(pathName.getPath()); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void parseXML(InputStream is) { + + SAXReader reader = new SAXReader(); + + try { + + Document doc = reader.read(is); + Element root = doc.getRootElement(); + Iterator it = root.elementIterator("action"); + + while (it.hasNext()){ + + Element ActionElement = (Element) it.next(); + + String actionName = ActionElement.attributeValue("name"); + String className = ActionElement.attributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, className); + + Iterator it2 = ActionElement.elementIterator(); + + while (it2.hasNext()){ + + Element resultElement = (Element) it2.next(); + + String resultName = resultElement.attributeValue("name"); + String viewName = resultElement.getTextTrim(); + + ac.addViewResult(resultName, viewName); + } + + this.actions.put(actionName, ac); + } + } catch (DocumentException e) { + e.printStackTrace(); + } + } + + public String getClassName(String actionName) { + ActionConfig ac = actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getClassName(); + } + + public String getResultView(String actionName, String resultName) { + ActionConfig ac = actions.get(actionName); + if (ac == null) { + return null; + } + return ac.getViewName(resultName); + + } + + + private static class ActionConfig{ + String name; + String clzName; + Map viewResult = new HashMap<>(); + + public ActionConfig(String name, String clzName) { + this.name = name; + this.clzName = clzName; + } + + public String getClassName() { + return clzName; + } + + public void addViewResult(String name, String viewName){ + viewResult.put(name, viewName); + + } + + public String getViewName(String resultName){ + return viewResult.get(resultName); + } + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java new file mode 100644 index 0000000000..39354518df --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java @@ -0,0 +1,39 @@ +package com.coding.litestruts; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..6b761355b1 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java @@ -0,0 +1,85 @@ +package com.coding.litestruts; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + + return getMethods(clz, "set"); + } + + public static void setParameters(Object o, Map params) { + + List methods = getSetterMethods(o.getClass()); + + for (String name : params.keySet()) { + + String methodName = "set" + name; + + for (Method method : methods) { + + if (method.getName().equalsIgnoreCase(methodName)){ + try { + method.invoke(o,params.get(name)); + + + + + + + } catch (IllegalAccessException | InvocationTargetException e) { + + e.printStackTrace(); + } + } + } + } + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz, "get"); + } + + private static List getMethods(Class clz, String startWithName) { + List methods = new ArrayList<>(); + + for (Method method : clz.getDeclaredMethods()) { + + if (method.getName().startsWith(startWithName)) { + methods.add(method); + } + } + return methods; + } + + public static Map getParamterMap(Object o) { + Map params = new HashMap<>(); + + List methods = getGetterMethods(o.getClass()); //获得"getXXX"方法 + + for (Method method : methods) { + + String methodName = method.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); //获得属性名 + + try { + params.put(name,method.invoke(o)); //将属性名 和属性值添加进去 + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + return params; + + } +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java new file mode 100644 index 0000000000..f446bec31c --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java @@ -0,0 +1,67 @@ +package com.coding.litestruts; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + + + public static View runAction(String actionName, Map parameters) throws NoSuchMethodException, IOException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + try { + Configuration cfg = new Configuration("struts.xml"); + + String clzName = cfg.getClassName(actionName); + if (clzName == null) { + return null; + } + String classPath = Struts.class.getClassLoader().getResource("").getPath(); + + System.out.println("clzName = " + clzName); + System.out.println("classPath = " + classPath); + Class clz = Class.forName(clzName); + + Object o = clz.newInstance(); + ReflectionUtil.setParameters(o, parameters); //将参数注入属性 + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String) m.invoke(o); //执行execute方法 + + Map params = ReflectionUtil.getParamterMap(o); //根据action获取model参数 + + String jsp = cfg.getResultView(actionName, resultName); //通过返回结果去拿视图名 + + View view = new View(); + view.setJsp(jsp); + view.setParameters(params); + return view; + } catch (IOException | InstantiationException | NoSuchMethodException | InvocationTargetException | ClassNotFoundException | IllegalAccessException e) { + e.printStackTrace(); + throw e; + } + } + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java new file mode 100644 index 0000000000..041fa4d889 --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java @@ -0,0 +1,47 @@ +package com.coding.litestruts; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } + + +} diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java new file mode 100644 index 0000000000..b6e795aa4a --- /dev/null +++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java @@ -0,0 +1,23 @@ +package com.coding.litestruts; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java new file mode 100644 index 0000000000..abd49e98e3 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java @@ -0,0 +1,122 @@ +package com.coding.basic.array; + +import com.coding.basic.Iterator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ArrayListTest { + + private ArrayList arrayList; + @Before + public void init() { + arrayList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + arrayList.add(i); + } + } + + @Test + public void size() throws Exception { + Assert.assertEquals(5, arrayList.size()); + arrayList.add(6); + Assert.assertEquals(6, arrayList.size()); + + } + + @Test + public void isEmpty() throws Exception { + arrayList.clear(); + Assert.assertEquals(0, arrayList.size()); + Assert.assertTrue(arrayList.isEmpty()); + } + + @Test + public void contains() throws Exception { + Assert.assertTrue(arrayList.contains(0)); + Assert.assertTrue(arrayList.contains(4)); + Assert.assertFalse(arrayList.contains(5)); + } + + @Test + public void toArray() throws Exception { + Integer[] integers = new Integer[]{0, 1, 2, 3, 4}; + Assert.assertArrayEquals(integers, arrayList.toArray()); + } + + @Test + public void add() throws Exception { + arrayList.add(5); + Assert.assertEquals(5, arrayList.get(arrayList.size() - 1).intValue()); + arrayList.add(0, 6); + arrayList.add(3, 7); + arrayList.add(arrayList.size(), 8); + + Assert.assertEquals(9, arrayList.size()); + Assert.assertEquals(6, arrayList.get(0).intValue()); + Assert.assertEquals(8, arrayList.get(arrayList.size()-1).intValue()); + Assert.assertEquals(7, arrayList.get(3).intValue()); + } + + @Test + public void remove() throws Exception { + arrayList.remove(0); + arrayList.remove(3); + arrayList.add(5); + Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{1,2,3,5}); + + arrayList.remove(new Integer(1)); + arrayList.remove(new Integer(2)); + arrayList.remove(new Integer(5)); + arrayList.add(6); + arrayList.add(7); + + Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{3,6,7}); + + } + + + + @Test + public void get() throws Exception { + Assert.assertEquals(0, arrayList.get(0).intValue()); + Assert.assertEquals(3, arrayList.get(3).intValue()); + arrayList.add(5); + arrayList.remove(0); + Assert.assertEquals(5, arrayList.get(4).intValue()); + } + + @Test + public void set() throws Exception { + arrayList.set(0,100); + arrayList.set(arrayList.size() - 1, 50); + Assert.assertEquals(100, arrayList.get(0).intValue()); + Assert.assertEquals(50, arrayList.get(arrayList.size() - 1).intValue()); + + } + + + + + + @Test + public void indexOf() throws Exception { + Assert.assertEquals(0, arrayList.indexOf(0)); + Assert.assertEquals(1, arrayList.indexOf(1)); + } + + @Test + public void iterator() throws Exception { + Iterator iterator = arrayList.iterator(); + Assert.assertTrue(iterator.hasNext()); + Assert.assertEquals(0, iterator.next()); + Assert.assertEquals(1, iterator.next()); + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java new file mode 100644 index 0000000000..f16a7ab5ab --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java @@ -0,0 +1,94 @@ +package com.coding.basic.array; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +/** + * Created by bobi on 2017/4/4. + * at code2017 + */ +public class ArrayUtilTest { + + private static int[] arr; + + @Before + public void setUp() throws Exception { + + arr = new int[10]; + + for (int i = 0; i < arr.length; i++) { + arr[i] = i; + } + + } + + private static void arrPrint(int[] arr){ + for (int i : arr) { + System.out.print(i + " "); + } + System.out.println(); + } + + @Test + public void reverseArray() throws Exception { + ArrayUtil.reverseArray(arr); + for (int i = 0; i < arr.length; i++) { + Assert.assertEquals(9-i, arr[i]); + } + } + + @Test + public void removeZero() throws Exception { + int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; + oldArr = ArrayUtil.removeZero(oldArr); + + Assert.assertArrayEquals(new int[]{1,3,4,5,6,6,5,4,7,6,7,5}, oldArr); + + } + + @Test + public void merge() throws Exception { + int[] a1 = {3, 5, 7,8}; + int[] a2 = {4, 5, 6,7} ; + + int[] a3 = ArrayUtil.merge(a1, a2); + Assert.assertArrayEquals(new int[]{3,4,5,6,7,8}, a3); + } + + @Test + public void grow() throws Exception { + int[] a1 = {3, 5, 7,8}; + a1 = ArrayUtil.grow(a1, 3); + + Assert.assertArrayEquals(new int[]{3,5,7,8,0,0,0}, a1); + } + + @Test + public void fibonacci() throws Exception { + int[] arr = ArrayUtil.fibonacci1(100); + arrPrint(arr); + } + + @Test + public void getPrimes() throws Exception { + int[] a1 = ArrayUtil.getPrimes(100); + arrPrint(a1); + } + + @Test + public void getPerfectNumbers() throws Exception { + int[] a1 = ArrayUtil.getPerfectNumbers(10000); + arrPrint(a1); + } + + @Test + public void join() throws Exception { + int[] a1 = {3,4,5,6,7}; + String str = ArrayUtil.join(a1, "-"); + System.out.println("str = " + str); + + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java new file mode 100644 index 0000000000..f020e64828 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java @@ -0,0 +1,155 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +/** + * Created by bobi on 2017/3/31. + * at code2017 + */ +public class LinkedListTest { + + + @Before + public void init() { + linkedList = new LinkedList<>(); + for (int i = 0; i < 6; i++) { + linkedList.add(1< linkedList; + + @Test + public void remove() throws Exception { + //测试添加删除 + { + linkedList.printf(); + linkedList.remove(new Integer(1)); + linkedList.remove(new Integer(8)); + linkedList.remove(new Integer(32)); + linkedList.add(50); + linkedList.add(0, 100); + Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100, 2, 4, 16, 50}); + +// + linkedList.remove(new Integer(16)); + linkedList.add(linkedList.size() - 1, 25); + Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100,2, 4, 25, 50}); + } + + } + + + @Test + public void removeFirstHalf() throws Exception { + linkedList.removeFirstHalf(); + linkedList.removeFirstHalf(); + linkedList.printf(); + } + + @Test + public void getElements() throws Exception { + + } + + @Test + public void subtract() throws Exception { + + } + + @Test + public void removeDuplicateValues() throws Exception { + linkedList.removeFirstHalf(); + LinkedList list = new LinkedList(); + list.add(8); + list.add(16); + list.add(32); + Assert.assertArrayEquals(linkedList.toArray(), list.toArray()); + linkedList.removeFirstHalf(); + list.remove(0); + Assert.assertArrayEquals(linkedList.toArray(), list.toArray()); + + } + + @Test + public void removeByLength() throws Exception { + // 测试删除开始节点 + { + linkedList.remove(0, 2); + Assert.assertEquals(linkedList.size(), 4); + for (int i = 0; i < 3; i++) { + Assert.assertEquals(linkedList.get(i).intValue(), 1<<(i+2)); + } + } + + // 测试删除中间节点 + { + init(); + linkedList.remove(1, 2); + Assert.assertEquals(linkedList.size(), 4); + Assert.assertEquals(linkedList.get(0).intValue(), 1); + Assert.assertEquals(linkedList.get(1).intValue(), 8); + Assert.assertEquals(linkedList.get(2).intValue(), 16); + } +// + // 测试删除末尾节点 + { + init(); + linkedList.remove(4, 2); + Assert.assertEquals(linkedList.size(), 4); + Assert.assertEquals(linkedList.get(0).intValue(), 1); + Assert.assertEquals(linkedList.get(1).intValue(), 2); + Assert.assertEquals(linkedList.get(2).intValue(), 4); + Assert.assertEquals(linkedList.get(3).intValue(), 8); + } +// + // 测试删除全部 + { + init(); + linkedList.remove(0, 6); + Assert.assertEquals(linkedList.size(), 0); + } + } + + @Test + public void intersection() throws Exception { + + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java new file mode 100644 index 0000000000..cd0d8abcc8 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java @@ -0,0 +1,68 @@ +package com.coding.basic.queue; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ArrayQueueTest { + private ArrayQueue arrayQueue; + + @Before + public void init(){ + arrayQueue = new ArrayQueue<>(6); + for (int i = 0; i < 5; i++) { + arrayQueue.add(i); + } + + } + @Test + public void add() throws Exception { + Assert.assertTrue(arrayQueue.add(5)); + + + Assert.assertEquals(0, arrayQueue.peek().intValue()); + Assert.assertEquals(0, arrayQueue.poll().intValue()); + Assert.assertEquals(1, arrayQueue.poll().intValue()); + + for (int i = 0; i < 4; i++) { + arrayQueue.remove(); + } + Assert.assertTrue(arrayQueue.isEmpty()); + } + + @Test + public void offer() throws Exception { + Assert.assertTrue(arrayQueue.offer(5)); + Assert.assertFalse(arrayQueue.offer(6)); + } + + @Test + public void remove() throws Exception { + arrayQueue.remove(); + arrayQueue.remove(); + arrayQueue.remove(); + arrayQueue.remove(); + + arrayQueue.add(5); + arrayQueue.add(6); + arrayQueue.add(7); + arrayQueue.add(8); + arrayQueue.add(9); + + + Assert.assertEquals(4, arrayQueue.remove().intValue()); + Assert.assertEquals(5, arrayQueue.remove().intValue()); + Assert.assertEquals(6, arrayQueue.remove().intValue()); + Assert.assertEquals(7, arrayQueue.remove().intValue()); + Assert.assertEquals(8, arrayQueue.remove().intValue()); + Assert.assertEquals(9, arrayQueue.remove().intValue()); + } + + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..40a3013741 --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java @@ -0,0 +1,45 @@ +package com.coding.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ConfigurationTest { + private Configuration config; + @Before + public void setUp() throws Exception { + config = new Configuration("struts.xml"); + } + + @After + public void tearDown() throws Exception { + + } + + + @Test + public void testGetClassName(){ + String clzName = config.getClassName("login"); + Assert.assertEquals("com.coding.litestruts.LoginAction", clzName); + clzName = config.getClassName("logout"); + Assert.assertEquals("com.coding.litestruts.LogoutAction", clzName); + + } + + @Test + public void testGetResultView(){ + String jsp = config.getResultView("login", "success"); + Assert.assertEquals("jsp/homepage.jsp", jsp); + + jsp = config.getResultView("login", "fail"); + Assert.assertEquals("jsp/showLogin.jsp", jsp); + } + +} \ No newline at end of file diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..d66188988b --- /dev/null +++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java @@ -0,0 +1,124 @@ +package com.coding.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Created by bobi on 2017/4/1. + * at code2017 + */ +public class ReflectionUtilTest { + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void testGetSetterMethod() throws ClassNotFoundException { + String name = "com.coding.litestruts.LoginAction"; + + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + List acctualNames = new ArrayList<>(); + for (Method method : methods) { + acctualNames.add(method.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + + } + + @Test + public void testSetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { + String name = "com.coding.litestruts.LoginAction"; + + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap<>(); + params.put("name", "test"); + params.put("password", "1234"); + + ReflectionUtil.setParameters(o, params); + + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + } + + + @Test + public void testGetGetterMethod() throws ClassNotFoundException { + String name = "com.coding.litestruts.LoginAction"; + + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + expectedNames.add("getMessage"); + + List acctualNames = new ArrayList<>(); + + for (Method method : methods) { + acctualNames.add(method.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + + } + + @Test + public void testGetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { + String name = "com.coding.litestruts.LoginAction"; + Class clz = Class.forName(name); + + LoginAction o = (LoginAction) clz.newInstance(); + o.setName("test"); + o.setPassword("123456"); + + Map params; + params = ReflectionUtil.getParamterMap(o); + + Assert.assertEquals(3, params.size()); + Assert.assertEquals(null, params.get("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + + + } + + @Test + public void testDouble(){ + double d = 6.02e23; + long i = (long) d; + System.out.println(i); + } +} \ No newline at end of file diff --git a/group04/120549547/my.txt b/group04/120549547/my.txt deleted file mode 100644 index 3da1ec26e9..0000000000 --- a/group04/120549547/my.txt +++ /dev/null @@ -1 +0,0 @@ -HelloWorld diff --git a/group04/1299310140/src/com/coderising/download/DownloadThread.java b/group04/1299310140/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..ba5dab2a78 --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,38 @@ +package com.coderising.download; + +import java.io.FileOutputStream; +import java.io.IOException; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + byte[] result; + + public DownloadThread( Connection conn, int startPos, int endPos, byte[] result){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.result = result; + + } + public void run(){ + try { + byte[] download = this.conn.read(this.startPos, this.endPos); + //synchronized(this.result){ + System.arraycopy(download, 0, this.result, this.startPos, download.length); + System.out.println(this.startPos+" "+this.endPos); + //} + FileOutputStream fos = new FileOutputStream("C:\\b.jpg"); + fos.write(this.result); + fos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/group04/1299310140/src/com/coderising/download/FileDownloader.java b/group04/1299310140/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..23520a9bd3 --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,83 @@ +package com.coderising.download; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm = new ConnectionManagerImpl(); + + public FileDownloader(String _url) { + this.url = _url; + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection connOne = null; + Connection connTwo = null; + Connection connThree = null; + try { + + connOne = cm.open(this.url); + connTwo = cm.open(this.url); + connThree = cm.open(this.url); + + int length = connOne.getContentLength(); + + byte[] result = new byte[length]; + new DownloadThread(connOne,0,length/3,result).start(); + new DownloadThread(connTwo,length/3+1,length/2,result).start(); + new DownloadThread(connThree,length/2+1,length-1,result).start(); + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(connOne != null){ + connOne.close(); + } + if(connTwo != null){ + connTwo.close(); + } + if(connThree != null){ + connThree.close(); + } + } + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + + public static void main(String[] args){ + new FileDownloader("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg").execute(); + } + +} diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..3628dd486f --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,59 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + private URLConnection urlconn; + private InputStream fis; + + public ConnectionImpl(URLConnection urlconn) { + super(); + this.urlconn = urlconn; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException{ + this.fis = this.urlconn.getURL().openStream(); + byte[] buffer = new byte[512]; + int count = 0;//某次read的字节数 + int sum = 0;//read的总字节数 + int length = endPos - startPos + 1;//当前线程需读取的字节数 + byte[] download = new byte[length]; + fis.skip(startPos); + while((count = fis.read(buffer)) != -1){ + if(sum + count >= length){ + System.arraycopy(buffer, 0, download, sum, length - sum); + sum = length; + break; + }else{ + System.arraycopy(buffer, 0, download, sum, count); + sum = sum + count; + } + } + return download; + } + + @Override + public int getContentLength() { + return this.urlconn.getContentLength(); + } + + @Override + public void close() { + if(this.fis != null){ + try { + this.fis.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + +} diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..3035ce9459 --- /dev/null +++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,31 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + try { + URL myurl = new URL("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg"); + URLConnection urlconn = myurl.openConnection(); + ConnectionImpl conn = new ConnectionImpl(urlconn); + return conn; + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + +} diff --git a/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..3b0b086ee4 --- /dev/null +++ b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,56 @@ +package com.coderising.jvm.loader; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.List; + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) throws Exception{ + //com.coderising.jvm.test.EmployeeV1 + //"com\\coderising\\jvm\\test\\EmployeeV1" + String clzFileName = this.getClassPath() + "\\" + className.replace(".", "\\") + ".class"; + //FileInputStream BufferedInputStream ByteArrayOutputStream + File file = new File(clzFileName); + + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + + int length = -1; + + while((length = bis.read(buffer)) != -1){ + bos.write(buffer,0,length); + } + + byte[] result = bos.toByteArray(); + bis.close(); + bos.close(); + + return result; + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + String result = ""; + for(int i = 0;i < clzPaths.size();i++){ + result = result + clzPaths.get(i); + if(i == clzPaths.size() - 1){ + break; + } + result = result + ";"; + } + return result; + } + +} diff --git a/group04/1299310140/src/com/coding/basic/LinkedList.java b/group04/1299310140/src/com/coding/basic/LinkedList.java index 4636bbd279..3e908613db 100644 --- a/group04/1299310140/src/com/coding/basic/LinkedList.java +++ b/group04/1299310140/src/com/coding/basic/LinkedList.java @@ -208,4 +208,285 @@ public String toString(){ return result; } } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(this.size <= 1){ + return; + } + Node before = null; + Node pres = this.head; + Node after = pres.next; + while(after != null){ + pres.next = before; + before = pres; + pres = after; + after = after.next; + } + //此时pres指向最后一个节点 + pres.next = before; + this.head = pres; + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + */ + public void removeFirstHalf(){ + if(this.size <= 1){ + return; + } + Node pres = this.head; + Node temp = pres; + for(int i = 0;i < this.size / 2;i++){ + temp = pres; + pres = pres.next; + temp.data = null; + temp.next = null; + } + this.head = pres; + this.size = this.size - this.size / 2; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param index + * @param length + */ + public void remove(int index, int length){//若length太大,size不够,则取到末尾 + if(index < 0 || index >= this.size || length <= 0){//index小于0or大于等于size,length小于等于0,参数错误 + return; + } + if(this.size <= 0){ + return; + } + if(index == 0){ + //此时index=0&&length>0&&size>0 + Node temp = this.head; + for(int i = 0;i < length;i++){ + temp = temp.next; + if(temp == null){ + break; + } + } + this.head = temp; + if(temp == null){ + this.size = 0; + }else{ + this.size = this.size - length; + } + }else{ + //此时00&&size>0 + Node start = this.head; + for(int j = 0;j < index-1;j++){ + start = start.next; + }//start指向index-1 + + Node end = start; + for(int l = 0;l <= length;l++){ + end = end.next; + if(end == null){ + break; + } + }//end指向index+length + start.next = end; + if(end == null){ + this.size = index; + }else{ + this.size = this.size - length; + } + } + } + + /** + * 假定当前链表和listB均包含已升序排列的整数 + * 从当前链表中取出那些listB所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){//若listB中的index不在0~this.size-1之中,则返回-1 + if(this.size <= 0 || list == null || list.size <= 0){ + return null; + } + + int[] result = new int[list.size()]; + Node presIndex = list.head; + int index = (int)presIndex.data; + for(int i = 0;i < list.size();i++){ + if(index < 0 || index >= this.size){ + result[i] = -1; + }else{//index:0~this.size-1 + result[i] = (int)this.get(index); + } + presIndex = presIndex.next; + if(presIndex != null){ + index = (int)presIndex.data; + } + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在listB中出现的元素 + * @param list + */ + public void subtract(LinkedList list){//当前链表以及参数列表均递增有序,可有重复值 + if(this.size == 0 || list == null || list.size() == 0){ + return; + } + + //头节点的删除比较特殊,先不予考虑 + Node thisPres = this.head.next;//指向被删除节点 + Node thisPresBefore = this.head;//指向被删除节点的前一个节点 + Node listPres = list.head; + while(thisPres != null && listPres != null){ + if((int)thisPres.data > (int)listPres.data){ + listPres = listPres.next; + }else if((int)thisPres.data < (int)listPres.data){ + thisPresBefore = thisPresBefore.next; + thisPres = thisPres.next; + }else{//(int)thisPres.data == (int)listPres.data + thisPresBefore.next = thisPres.next; + thisPres = thisPres.next; + this.size--; + } + } + + //最后考虑头节点的删除情况 + Node first = this.head; + Node listPresTwo = list.head; + while((int)first.data > (int)listPresTwo.data){ + listPresTwo = listPresTwo.next; + } + if((int)first.data == (int)listPresTwo.data){//删除头节点 + this.head = this.head.next; + this.size--; + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + if(this.size <= 1){ + return; + } + + Node start = this.head; + Node end = start.next; + while(end != null){ + if((int)start.data != (int)end.data){ + start = end; + end = end.next; + }else{//start.data == end.data + while((int)start.data == (int)end.data){ + end = end.next; + if(end == null){ + break; + } + } + start.next = end; + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + if(this.size == 0 || max - min < 2 || (int)this.head.data >= max){ + return; + } + + //this.size >= 1 && max - min >= 2 && this.head.data < max + int thisHeadData = (int)this.head.data; + if(thisHeadData > min && thisHeadData < max){ + //this.size >= 1 && max - min >= 2 && + //min < this.head.data < max + //找到新的头节点即可,this.size减小 + Node notSmallToMax = this.head.next; + int sizeDec = 1; + while(notSmallToMax != null){ + if((int)notSmallToMax.data >= max){ + break; + } + notSmallToMax = notSmallToMax.next; + sizeDec++; + } + this.head = notSmallToMax; + this.size = this.size - sizeDec; + }else{ + //this.size >= 1 && max - min >= 2 && + //this.head.data <= min + Node startBefore = this.head;//第一个>min节点的前一个节点 + Node start = startBefore.next;//第一个>min的节点 + while(start != null){ + if((int)start.data > min){ + break; + } + startBefore = start; + start = start.next; + } + if(start == null || (int)start.data >= max){ + //链表中不存在满足删除条件的元素 + return; + } + + //至少有一个元素需要被删除 + int sizeDec = 1; + Node end = start;//最后一个= max){ + break; + } + end = endAfter; + endAfter = endAfter.next; + sizeDec++; + } + startBefore.next = endAfter; + this.size = this.size - sizeDec; + } + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection(LinkedList list){ + if(list == null || list.size() == 0){ + return new LinkedList(); + } + if(this.size == 0){ + return new LinkedList(); + } + LinkedList result = new LinkedList(); + Node thisPres = this.head; + Node listPres = list.head; + while(thisPres != null && listPres != null){ + if((int)thisPres.data < (int)listPres.data){ + thisPres = thisPres.next; + }else if((int)thisPres.data > (int)listPres.data){ + listPres = listPres.next; + }else{ + //(int)thisPres.data == (int)listPres.data + result.add(thisPres.data); + thisPres = thisPres.next; + listPres = listPres.next; + } + } + return result; + } } diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..025327e934 --- /dev/null +++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,136 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * @author liuxin + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + + } + + private int capacity; + private int size = 0; + private Node first;// 链表头 + private Node last;// 链表尾 + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + removeElement(pageNum); + addFirst(pageNum); + if(this.size > this.capacity){ + removeLast(); + } + } + + //删除链表的尾节点 + private void removeLast(){ + if(this.size == 0){ + return; + } + if(this.size == 1){ + this.first = null; + this.last = null; + this.size--; + } + Node curr = this.last; + this.last = curr.prev; + this.last.next = null; + curr.prev = null; + this.size--; + } + + //根据参数删除双向链表中的某个节点 + private void removeElement(int pageNum){ + if(this.size == 0){ + return; + } + Node curr = this.first; + while(curr.pageNum != pageNum){ + if(curr.next == null){ + break; + } + curr = curr.next; + } + //此时curr指向被删除节点or链表最后一个节点 + if(curr.pageNum == pageNum){ + if(this.first == this.last){//size为1,且该节点需要被删除 + this.first = null; + this.last = null; + this.size--; + return; + } + if(curr == this.first){//删除头节点 + this.first = curr.next; + this.first.prev = null; + curr.next = null; + this.size--; + return; + } + if(curr == this.last){//删除尾节点 + this.last = curr.prev; + this.last.next = null; + curr.prev = null; + this.size--; + return; + } + + //删除中间节点 + //此时size至少为3 + curr.next.prev = curr.prev; + curr.prev.next = curr.next; + curr.prev = null; + curr.next = null; + this.size--; + } + } + + //向双向链表的头部添加节点 + private void addFirst(int pageNum){ + Node curr = new Node(pageNum); + if(this.size == 0){ + this.first = curr; + this.last = curr; + this.size++; + }else{ + curr.next = this.first; + this.first.prev = curr; + this.first = curr; + this.size++; + } + } + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + +} diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..52347f721d --- /dev/null +++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,73 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; +import org.junit.Test; + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(7); + frame.access(0); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + + LRUPageFrame frameFive = new LRUPageFrame(5); + frameFive.access(7);//7 + frameFive.access(7);//7 + frameFive.access(0);//0 7 + frameFive.access(7);//7 0 + frameFive.access(0);//0 7 + frameFive.access(1);//1 0 7 + Assert.assertEquals("1,0,7", frameFive.toString()); + frameFive.access(2);//2 1 0 7 + Assert.assertEquals("2,1,0,7", frameFive.toString()); + frameFive.access(0);//0 2 1 7 + Assert.assertEquals("0,2,1,7", frameFive.toString()); + frameFive.access(0);//0 2 1 7 + Assert.assertEquals("0,2,1,7", frameFive.toString()); + frameFive.access(3);//3 0 2 1 7 + Assert.assertEquals("3,0,2,1,7", frameFive.toString()); + frameFive.access(0);//0 3 2 1 7 + Assert.assertEquals("0,3,2,1,7", frameFive.toString()); + frameFive.access(4);//4 0 3 2 1 + Assert.assertEquals("4,0,3,2,1", frameFive.toString()); + } + +// @Test +// public void testAddFirst(){ +// LRUPageFrame frame = new LRUPageFrame(3); +// frame.addFirst(1); +// frame.addFirst(2); +// Assert.assertEquals("2,1", frame.toString()); +// frame.addFirst(3); +// Assert.assertEquals("3,2,1", frame.toString()); +// frame.addFirst(4); +// Assert.assertEquals("4,3,2,1", frame.toString()); +// frame.removeElement(3); +// Assert.assertEquals("4,2,1", frame.toString()); +// frame.removeElement(1); +// Assert.assertEquals("4,2", frame.toString()); +// frame.removeElement(4); +// Assert.assertEquals("2", frame.toString()); +// frame.removeElement(2); +// Assert.assertEquals("", frame.toString()); +// } + +} diff --git a/group04/1796244932/learn01/1.png b/group04/1796244932/learn01/1.png new file mode 100644 index 0000000000..a25be7d057 Binary files /dev/null and b/group04/1796244932/learn01/1.png differ diff --git a/group04/1796244932/learn01/pom.xml b/group04/1796244932/learn01/pom.xml index 06c26f00c8..f62b63ec4b 100644 --- a/group04/1796244932/learn01/pom.xml +++ b/group04/1796244932/learn01/pom.xml @@ -21,17 +21,29 @@ dom4j 1.6 + + + + + org.jdom + jdom + 2.0.2 + + + junit junit - 4.11 - test + 4.12 - - org.junit.jupiter - junit-jupiter-api - RELEASE - + + + + io.netty + netty + 4.0.0.Alpha8 + + diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java index 60254997aa..a425f54e81 100644 --- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java @@ -1,6 +1,13 @@ package com.dudy.learn01.base; +import java.util.LinkedList; + +/** + * 单链表: + * 因为没有尾节点 + * 存放时 add 1 2 3 4 实际是 4 3 2 1 + */ public class MyLinkedList implements MyList { private int size = 0; @@ -24,6 +31,7 @@ public void add(int index, Object o) { } private Node getCurrentNode(int index) {// 获取当前节点 + checkRange(index); Node current = head; for(int i = 0; i< size-index -1; i++){ current = current.next; @@ -56,7 +64,7 @@ public Object remove(int index) { return node.data; } - public int size() { + public int size() { return size; } @@ -108,6 +116,7 @@ public Object next() { } } + private static class Node { Object data; Node next; @@ -118,15 +127,107 @@ public Node(Object data) { } } - - private void displayLink() {// 自己调试使用 - Node current = head; - while(current != null){ - System.out.print(current.data); - current = current.next; + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + + if(head == null || head.next == null){ + return ; + } + + Node current = head; // 当前节点 我的头节点是有数据的 + + while (current.next != null){ + Node p = current.next; // 当前节点的下一个 + current.next = p.next; // 当前节点的next -> current.next.next (p.next) + p.next = head; // current.next(p) -> head.next (插入到 head 和 第一个数据之间) + head = p; } - System.out.println(""); } - + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + + int base = size; + Node currentNode = getCurrentNode(base / 2); + currentNode = null; + size = size - base/2; + } + + /** + * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 + * @param i + * @param length + */ + public void remove(int i, int length){ + + Node preNode = getCurrentNode(size - i -1); + Node nextNode = getCurrentNode(size - i - length-1); + nextNode.next = preNode; + size = size -length; + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param src + */ + public Object[] getElements(int[] src){ + Object des[] = new Object[src.length]; + + for (int i = 0; i < src.length; i++){ + des[i] = getCurrentNode(size - 1 - i).data; + } + + return des; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max){ + + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + return null; + } } \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java new file mode 100644 index 0000000000..84e9bd5d2c --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java @@ -0,0 +1,40 @@ +package com.dudy.learn01.designPattern.singleton; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by dudy on 2017/3/6. + */ +public enum EnumSingleton { + + SINGLETON; + private EnumSingleton(){} + + + public static void main(String[] args) { + + ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 6000 * 10, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue(5)); + + + for (int i = 0; i< 16; i++){ + executor.execute(new EnumSingletonTest()); + } + + executor.shutdown(); + + + } +} + + +class EnumSingletonTest implements Runnable{ + + @Override + public void run() { + EnumSingleton singleton = EnumSingleton.SINGLETON; + System.out.println(singleton.hashCode()); + } +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java new file mode 100644 index 0000000000..8de831c354 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java @@ -0,0 +1,66 @@ +package com.dudy.learn01.designPattern.singleton; + +import java.io.Serializable; +import java.util.concurrent.*; + +/** + * Created by dudy on 2017/3/6. + * 双检索 方式 + * jdk1.5 以后 其实是线程安全的。 + * 序列化会 破坏 单利 + * + */ +public class SingletonDemo1 implements Serializable{ + + private static volatile SingletonDemo1 singleton = null; // 加 volatile 是为了 可见性,另一个就是 避免重排序 + + private SingletonDemo1(){} + + public static SingletonDemo1 getIntance(){ + + if (singleton == null){// 第一个避免 在 synchronized 中 一直排队 + synchronized (SingletonDemo1.class){ + + if (singleton == null){// 如果对象为空,才被创建 + singleton = new SingletonDemo1(); + } + + } + } + + return singleton; + } + + + /** + * 解决 反序列化的问题 + * @return + */ + private Object readResolve() { + return singleton; + } + + public static void main(String[] args) { + + ExecutorService threadPool = Executors.newFixedThreadPool(10); + + for (int i= 0 ;i < 5; i++){ + threadPool.execute(new TestRunable()); + } + + threadPool.shutdown(); + + //new ThreadPoolExecutor(10,20,1000*2,new BlockingQueue(),) + + + } + +} + + class TestRunable implements Runnable{ + + public void run() { + SingletonDemo1 intance = SingletonDemo1.getIntance(); + System.out.println(intance.hashCode()); + } + } diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java new file mode 100644 index 0000000000..d8b484cd15 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java @@ -0,0 +1,63 @@ +package com.dudy.learn01.designPattern.singleton; + +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by dudy on 2017/3/6. + * + * 静态内部类方式 实现 + * + * 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程, + * 它跟饿汉式不同的是(很细微的差别):饿汉式是只要Singleton类被装载了, + * 那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了, + * instance不一定被初始化。因为SingletonHolder类没有被主动使用, + * 只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类, + * 从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载, + * 另外一方面,我不希望在Singleton类加载时就实例化, + * 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载, + * 那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比饿汉式更加合理 + * + */ +public class StaticClassInnerSingleton { + + // 构造器 私有化 + private StaticClassInnerSingleton(){} + + private static class SingletonHolder{ + private static final StaticClassInnerSingleton INSTANCE = new StaticClassInnerSingleton(); + } + + + public static StaticClassInnerSingleton getInstance(){ + return SingletonHolder.INSTANCE; + } + + + public static void main(String[] args) { + + + ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, + 6000 * 10, TimeUnit.MILLISECONDS, + new LinkedBlockingDeque()); + + for (int i= 0; i<20; i++){ + pool.execute(new StaicSingletonTest()); + //System.out.println(StaticClassInnerSingleton.getInstance().hashCode()); + } + + pool.shutdown(); + } + + + +} + +class StaicSingletonTest implements Runnable{ + + public void run() { + StaticClassInnerSingleton intance = StaticClassInnerSingleton.getInstance(); + System.out.println(intance.hashCode()); + } +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java new file mode 100644 index 0000000000..97ca01e13b --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java @@ -0,0 +1,59 @@ +package com.dudy.learn01.download; + +import com.dudy.learn01.download.api.Connection; + +import java.io.*; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; + +public class DownloadThread extends Thread{ + + private Connection conn; + private int startPos; + private int endPos; + private RandomAccessFile raf; + //private CyclicBarrier cb; + private CountDownLatch downLatch; + + + public DownloadThread(Connection conn, int startPos, int endPos, + /*CyclicBarrier cb*/ + CountDownLatch downLatch){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; +// this.cb = cb; + this.downLatch = downLatch; + } + public void run(){ + try { + byte[] read = conn.read(startPos, endPos); + + System.out.println("read length: -> "+read.length); + //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的 + raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw"); + //将写文件的指针指向下载的起始点 + raf.seek(startPos); + raf.write(read, 0, read.length); + + downLatch.countDown(); +// cb.await(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (raf != null){ + raf.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + if (conn != null){ + conn.close(); + } + + } + } +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java new file mode 100644 index 0000000000..eee5825b84 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java @@ -0,0 +1,93 @@ +package com.dudy.learn01.download; + +import com.dudy.learn01.download.api.Connection; +import com.dudy.learn01.download.api.ConnectionManager; +import com.dudy.learn01.download.api.DownloadListener; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; + +public class FileDownloader { + + private static final int THREAD_NUM = 3; + + private String url; + + private DownloadListener listener; + + private ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() throws IOException { + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + //CyclicBarrier cb = new CyclicBarrier(THREAD_NUM); + CountDownLatch downLatch = new CountDownLatch(THREAD_NUM); + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + for (int i = 0;i < THREAD_NUM; i++){ + + int start=i*length/THREAD_NUM; + int end = (i+1)*length/THREAD_NUM-1; + if(i==THREAD_NUM-1) + { + end =length; + } + + new DownloadThread(cm.open(url),start,end,downLatch).start(); + } + + //cb.await(); + downLatch.await(); + getListener().notifyFinished(); + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java new file mode 100644 index 0000000000..513c0004e9 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.dudy.learn01.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java new file mode 100644 index 0000000000..71af9bf06d --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.dudy.learn01.download.api; + +public class ConnectionException extends Exception { + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java new file mode 100644 index 0000000000..5f4777f6e0 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java @@ -0,0 +1,13 @@ +package com.dudy.learn01.download.api; + +import java.io.IOException; +import java.net.MalformedURLException; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException, IOException; +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java new file mode 100644 index 0000000000..fa3b5bead0 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.dudy.learn01.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..5eb6b45d41 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java @@ -0,0 +1,89 @@ +package com.dudy.learn01.download.impl; + +import com.dudy.learn01.download.api.Connection; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ConnectionImpl implements Connection { + + + private HttpURLConnection connection; + + public ConnectionImpl(String url) { + try { + this.connection = (HttpURLConnection) new URL(url).openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream in = connection.getInputStream(); + byte buffer[] = new byte[endPos-startPos+1]; + byte result[] = new byte[endPos-startPos+1]; + int count = 0; // 记录已经读取的数据 + int length = -1 ; + + while ((length = in.read(buffer)) > 0){ + System.arraycopy(buffer,0,result,count,length); + count += length; + } + return result; + } + + @Override + public int getContentLength() { + return connection.getContentLength(); + } + + @Override + public void close() { + if (connection != null){ + connection.disconnect(); + } + } + + public static void main(String[] args) throws Exception{ + //String PATH = "http://demo2.yun.myuclass.com/upload/demo2.yun.myuclass.com/winshare/pagelogo/250617391.png"; + String PATH = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png"; + + URL url = new URL(PATH); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + //conn.setConnectTimeout(5000); + //conn.setRequestMethod("GET"); + //设置头部的参数,表示请求服务器资源的某一部分 + //conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + //设置了上面的头信息后,响应码为206代表请求资源成功,而不再是200 + int code = conn.getResponseCode(); + System.out.println(conn.getContentLength()); + if(code == 200){ + + InputStream is = conn.getInputStream(); + int hasRead = 0; + byte[] buf = new byte[conn.getContentLength()]; + System.out.println(buf.length); + //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的 + RandomAccessFile raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw"); + //将写文件的指针指向下载的起始点 + raf.seek(0); + + while((hasRead = is.read(buf,0,conn.getContentLength())) > 0) { + System.out.println("hasRead = " + hasRead); + raf.write(buf, 0, hasRead); + } + is.close(); + raf.close(); + conn.disconnect(); + } + } + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..809f98d91b --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,25 @@ +package com.dudy.learn01.download.impl; + +import com.dudy.learn01.download.api.Connection; +import com.dudy.learn01.download.api.ConnectionException; +import com.dudy.learn01.download.api.ConnectionManager; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + + private Connection connection = null; + + @Override + public Connection open(String url) throws ConnectionException, IOException { + + connection = new ConnectionImpl(url); + + return connection; + } + +} \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java new file mode 100644 index 0000000000..e4239ae521 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java @@ -0,0 +1,64 @@ +package com.dudy.learn01.juc; + +/** + * Created by dudy on 2017/3/9. + * + * 4. ThreadLocal 这个类实现原理和用途,在哪里用到了 + * 每个ThreadLocal可以放一个线程级别的变量,但是它本身可以被多个线程共享变量,而且又可以达到线程安全的目的,且绝对线程安全 + * spring的事物管理Session, 连接池管理 Connection + * https://my.oschina.net/huangyong/blog/159725 + * 数据库事物的前提是: 必须是同一个连接 + */ +public class ThreadLocalTest { + + static class Resource{ + public static final ThreadLocal RESOURCE1 = new ThreadLocal(); + public static final ThreadLocal RESOURCE2 = new ThreadLocal(); + } + + static class A { + public void setOne(String str){ + Resource.RESOURCE1.set(str); + } + + public void setTwo(String str){ + Resource.RESOURCE2.set(str); + } + } + + static class B { + public void display(){ + System.out.println(Resource.RESOURCE1.get() + +":" + Resource.RESOURCE2.get()); + } + } + + public static void main(String[] args) { + + final A a = new A(); + final B b = new B(); + + for (int i = 0; i< 5 ;i++){ + + final String resource1 = "Thread_" + i; + final String resource2 = "value " + i; + + new Thread(new Runnable() { + @Override + public void run() { + try { + a.setOne(resource1); + a.setTwo(resource2); + b.display(); + }finally { + Resource.RESOURCE2.remove(); + Resource.RESOURCE1.remove(); + } + } + }).start(); + } + + } + + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java index bbe8c108ca..c08ae7ae49 100644 --- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java @@ -46,6 +46,7 @@ public static View runAction(String actionName, Map parameters) { for (Map.Entry entry : parameters.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); // 这里 只能传递object吧 + //actionClass.gett Method method = actionClass.getDeclaredMethod(methodNameconversion(entry.getKey()), String.class); method.setAccessible(true); method.invoke(base,entry.getValue()); diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java new file mode 100755 index 0000000000..987696acde --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java @@ -0,0 +1,113 @@ +package com.dudy.learn01.litestruts.format; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; + +public class Configuration { + + Map actions = new HashMap<>(); + + public Configuration(String fileName) { + + String packageName = this.getClass().getPackage().getName(); + + packageName = packageName.replace('.', '/'); + + InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + private void parseXML(InputStream is){ + + SAXBuilder builder = new SAXBuilder(); + + try { + + Document doc = builder.build(is); + + Element root = doc.getRootElement(); + + for(Element actionElement : root.getChildren("action")){ + + String actionName = actionElement.getAttributeValue("name"); + String clzName = actionElement.getAttributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, clzName); + + for(Element resultElement : actionElement.getChildren("result")){ + + String resultName = resultElement.getAttributeValue("name"); + String viewName = resultElement.getText().trim(); + + ac.addViewResult(resultName, viewName); + + } + + this.actions.put(actionName, ac); + } + + + } catch (JDOMException e) { + throw new ConfigurationException(e); + + } catch (IOException e) { + throw new ConfigurationException(e); + + } + + + } + + public String getClassName(String action) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getClassName(); + } + + public String getResultView(String action, String resultName) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getViewName(resultName); + } + + private static class ActionConfig{ + + String name; + String clzName; + Map viewResult = new HashMap<>(); + + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + public String getClassName(){ + return clzName; + } + public void addViewResult(String name, String viewName){ + viewResult.put(name, viewName); + } + public String getViewName(String resultName){ + return viewResult.get(resultName); + } + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java new file mode 100755 index 0000000000..a584a7077d --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.dudy.learn01.litestruts.format; + +import java.io.IOException; + +import org.jdom2.JDOMException; + +public class ConfigurationException extends RuntimeException { + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java new file mode 100755 index 0000000000..0f3c74e69a --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.dudy.learn01.litestruts.format; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ConfigurationTest { + + + Configuration cfg = new Configuration("struts.xml"); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetClassName() { + + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName); + + + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName); + } + + @Test + public void testGetResultView(){ + String jsp = cfg.getResultView("login","success"); + Assert.assertEquals("/jsp/homepage.jsp", jsp); + + jsp = cfg.getResultView("login","fail"); + Assert.assertEquals("/jsp/showLogin.jsp", jsp); + + jsp = cfg.getResultView("logout","success"); + Assert.assertEquals("/jsp/welcome.jsp", jsp); + + jsp = cfg.getResultView("logout","error"); + Assert.assertEquals("/jsp/error.jsp", jsp); + + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java new file mode 100755 index 0000000000..3672d5a990 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java @@ -0,0 +1,39 @@ +package com.dudy.learn01.litestruts.format; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java new file mode 100755 index 0000000000..6ab3715730 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.dudy.learn01.litestruts.format; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + + return getMethods(clz,"set"); + + } + + public static void setParameters(Object o, Map params) { + + List methods = getSetterMethods(o.getClass()); + + for(String name : params.keySet() ){ + + String methodName = "set" + name; + + for(Method m: methods){ + + if(m.getName().equalsIgnoreCase(methodName)){ + try { + m.invoke(o, params.get(name)); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz,"get"); + } + + private static List getMethods(Class clz, String startWithName){ + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith(startWithName)){ + + methods.add(m); + + } + + } + + return methods; + } + + public static Map getParamterMap(Object o) { + + Map params = new HashMap<>(); + + List methods = getGetterMethods(o.getClass()); + + for(Method m : methods){ + + String methodName = m.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); + try { + Object value = m.invoke(o); + params.put(name, value); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + + e.printStackTrace(); + } + } + + return params; + } + + ////////////////////////Backup /////////////////////////////////// + + public static List getGetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("get")){ + + methods.add(m); + + } + + } + + return methods; + } + + public static List getSetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("set")){ + + methods.add(m); + + } + + } + + return methods; + + } + + + + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java new file mode 100755 index 0000000000..174808fe62 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java @@ -0,0 +1,113 @@ +package com.dudy.learn01.litestruts.format; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ReflectionUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetSetterMethod() throws Exception { + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception{ + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + ReflectionUtil.setParameters(o,params); + + + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + f = clz.getDeclaredField("password"); + f.setAccessible(true); + Assert.assertEquals("1234", f.get(o)); + } + @Test + public void testGetGetterMethod() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getMessage"); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testGetParamters() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + LoginAction action = (LoginAction)clz.newInstance(); + action.setName("test"); + action.setPassword("123456"); + + + + + Map params = ReflectionUtil.getParamterMap(action); + + Assert.assertEquals(3, params.size()); + + Assert.assertEquals(null, params.get("messaage") ); + Assert.assertEquals("test", params.get("name") ); + Assert.assertEquals("123456", params.get("password") ); + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java new file mode 100755 index 0000000000..661fd96ebe --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java @@ -0,0 +1,68 @@ +package com.dudy.learn01.litestruts.format; + +import java.lang.reflect.Method; +import java.util.Map; + + + +public class Struts { + + private final static Configuration cfg = new Configuration("struts.xml"); + + public static View runAction(String actionName, Map parameters) { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + + String clzName = cfg.getClassName(actionName); + + if(clzName == null){ + return null; + } + + try { + + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + + ReflectionUtil.setParameters(action, parameters); + + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String)m.invoke(action); + + Map params = ReflectionUtil.getParamterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + + + + } catch (Exception e) { + + e.printStackTrace(); + } + return null; + } + +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java new file mode 100755 index 0000000000..f3b177e54c --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java @@ -0,0 +1,43 @@ +package com.dudy.learn01.litestruts.format; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java new file mode 100755 index 0000000000..93c73bd359 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java @@ -0,0 +1,23 @@ +package com.dudy.learn01.litestruts.format; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml new file mode 100755 index 0000000000..4c6eeabbd4 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + \ No newline at end of file diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java new file mode 100644 index 0000000000..2763af6d55 --- /dev/null +++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java @@ -0,0 +1,104 @@ +package com.dudy.learn01.utils; + +import java.util.Arrays; + +/** + * Created by dudy on 2017/3/6. + * 练习数组的各种排序 + * 参考:http://wiki.jikexueyuan.com/project/java-special-topic/sort.html + * http://www.cnblogs.com/liuling/p/2013-7-24-01.html + * + * 内排序有可以分为以下几类: + +   (1)、插入排序:直接插入排序、二分法插入排序、希尔排序。 + +   (2)、选择排序:简单选择排序、堆排序。 + +   (3)、交换排序:冒泡排序、快速排序。 + +   (4)、归并排序 + +   (5)、基数排序 + * + */ +public class ArraySortDemo { + + + /** + * 二分法查找 插入 + * 和 直接插入排序不同的是: 查找 要插入的位置的方式不同 + * 二分法前提是有序的** + */ + public static void dichotomySort(int src[]){ + + for (int i = 0; i< src.length ; i++){ + int temp = src[i]; + int right = i - 1; + int mid = 0; + int left = 0; + while (left <= right){ + mid = (left + right)/2; + if (temp > src[mid]){ + left = mid + 1; + } else { + right = mid - 1; + } + } + + for (int j = i-1;j>=left ; j--){ + src[j+1] = src[j]; + } + + System.out.println("left = " + left +" ,mid = " + mid + " ,right = " + right); + src[left] = temp; + + } + } + + + + + /** + * 直接插入排序 + * 思想:假定前边是有序地部分, 后边无序的插入到前边部分 + * 可以转变思想: 从后往前遍历, 将有序部分大于当前的值 往后移 + * @param src + */ + public static void directInsertSort(int[] src){ + + for (int i = 1;i < src.length ; i++){ + // 待插入的元素 + int temp = src[i]; + int j; + for ( j = i -1; j >= 0; j--){ + // 大于 temp的往后移动 + if (src[j] > temp){ + src[j+1] = src[j]; + } else { + break; + } + }// 此时遍历完 j+1 为要插入的位置 + src[j+1] = temp; + } + + } + + + + public static void main(String[] args) { + int a[] = new int[]{46,89,14,44,90,32,25,67,23}; + // 14,23,25,32,44,46,67,89,90 + //Arrays.sort(a); + + + //directInsertSort(a); + + dichotomySort(a); + + for (int i = 0; i< a.length ; i++){ + System.out.print(a[i] + ","); + } + + } + +} diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java index c6ebb096ec..cce7a1c163 100644 --- a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java +++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java @@ -2,10 +2,69 @@ import java.util.LinkedList; +import org.junit.After; +import org.junit.Before; import org.junit.Test; public class MyLinkedListTest { + MyLinkedList list = new MyLinkedList(); + + @Before + public void init(){ + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + } + + @After + public void after(){ + for(MyIterator it = list.iterator(); it.hasNext();){ + System.out.print(it.next() + " "); + } + } + + @Test + public void reverse() throws Exception { + list.reverse(); + } + + @Test + public void removeFirstHalf() throws Exception { + list.removeFirstHalf(); + } + + @Test + public void remove() throws Exception { + list.remove(0,2); + } + + @Test + public void getElements() throws Exception { + + } + + @Test + public void subtract() throws Exception { + + } + + @Test + public void removeDuplicateValues() throws Exception { + + } + + @Test + public void removeRange() throws Exception { + + } + + @Test + public void intersection() throws Exception { + + } @Test diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java new file mode 100644 index 0000000000..fc427e2171 --- /dev/null +++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java @@ -0,0 +1,53 @@ +package com.dudy.learn01.download; + +import com.dudy.learn01.download.api.ConnectionManager; +import com.dudy.learn01.download.api.DownloadListener; +import com.dudy.learn01.download.impl.ConnectionManagerImpl; +import org.junit.Test; + + +import java.io.IOException; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + + + + @Test + public void testDownload() throws IOException { + + //String url = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png"; + String url = "http://img.lanrentuku.com/img/allimg/1606/14665573271238.jpg"; + FileDownloader downloader = new FileDownloader(url); + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} \ No newline at end of file diff --git a/group04/349184132/Study/bin/com/test/student2.xml b/group04/349184132/Study/bin/com/test/student2.xml deleted file mode 100644 index e21862ec75..0000000000 --- a/group04/349184132/Study/bin/com/test/student2.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - hello text - world text - diff --git a/group04/349184132/Study/bin/com/test/students.xml b/group04/349184132/Study/bin/com/test/students.xml deleted file mode 100644 index 0a503c9f6c..0000000000 --- a/group04/349184132/Study/bin/com/test/students.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - hello Text1 - hello Text2 - hello Text3 - world text1 - world text2 - world text3 - \ No newline at end of file diff --git a/group04/349184132/Study/src/com/coderising/download/DownloadThread.java b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..2b806a7f44 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,49 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread { + Connection conn; + int startPos; + int endPos; + int threadId = 0; + CyclicBarrier barrier; + + public DownloadThread(CyclicBarrier barrier, Connection conn, int threadId, + int startPos, int endPos) { + this.barrier = barrier; + this.conn = conn; + this.threadId = threadId; + this.startPos = startPos; + this.endPos = endPos; + } + + public void run() { + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile("yunpan.exe", "rwd"); + + raf.seek(startPos); + + byte[] buffer = conn.read(startPos, endPos); + + raf.write(buffer, 0, buffer.length); + raf.close(); + barrier.await(); + System.out.println("threadId" + threadId +"download success !"); + + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + + } +} diff --git a/group04/349184132/Study/src/com/coderising/download/FileDownloader.java b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..281dafde96 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,112 @@ +package com.coderising.download; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.net.URL; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +public class FileDownloader { + + boolean isFinished = false; + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + private static final int THREAD_NUM = 3; + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute() { + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, + // endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, + // 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + + CyclicBarrier barrier = new CyclicBarrier(THREAD_NUM,new Runnable(){ + + @Override + public void run() { + listener.notifyFinished(); + } + + }); + + Connection conn = null; + try { + conn = cm.open(url); + + int length = conn.getContentLength(); + System.out.println("----文件总长度---- :" + length); + RandomAccessFile raf = new RandomAccessFile("yunpan.exe","rwd"); + + raf.setLength(length); + + int block = length / THREAD_NUM; + + for(int threadId = 0; threadId < THREAD_NUM; threadId++){ + int startPos = (threadId) * block; + int endPos = (threadId + 1 ) * block -1; + if(threadId-1 == THREAD_NUM){ + endPos = length; + } + System.out.println("---threadId--- :" + threadId + + "---startIndex---" + startPos + + "---endIndex---" + endPos); + //开启 线程 + URL u = new URL(url); + new DownloadThread(barrier,cm.open(url),threadId,startPos,endPos).start(); + } + + + } catch (ConnectionException e) { + + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally{ + if(conn!=null){ + conn.close(); + } + } + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + public void setConnectionManager(ConnectionManager ucm) { + this.cm = ucm; + } + + public DownloadListener getListener() { + return this.listener; + } + + +} diff --git a/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..604712d2a9 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,58 @@ +package com.coderising.download; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://down.360safe.com/yunpan/360wangpan_setup.exe"; + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + +// 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/Connection.java b/group04/349184132/Study/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..1599be1296 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(String string) { + // TODO 自动生成的构造函数存根 + } + + +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..3ad903146b --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,52 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + private HttpURLConnection conn ; + public ConnectionImpl(HttpURLConnection conn) { + this.conn = conn; + } + @Override + public byte[] read(int startPos, int endPos) throws IOException { + conn.setRequestMethod("GET"); + conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + conn.setConnectTimeout(5000); + + InputStream is = conn.getInputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int length = 0; + byte[] buffer = new byte[1024]; + while(-1 != ( length = is.read(buffer))){ + bos.write(buffer,0,length); + } + bos.flush(); + is.close(); + bos.close(); + + + return bos.toByteArray(); + } + + @Override + public int getContentLength() { + + return conn.getContentLength(); + } + + @Override + public void close() { + if(conn!=null){ + conn = null; + } + } + +} diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..9132787cf8 --- /dev/null +++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,37 @@ +package com.coderising.download.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + @Override + public Connection open(String url) throws ConnectionException { + + URL u; + HttpURLConnection hc ; + try { + u = new URL(url); + hc = (HttpURLConnection) u.openConnection(); + Connection conn = new ConnectionImpl(hc);; + return conn; + } catch (MalformedURLException e) { + e.printStackTrace(); + + } catch (IOException e) { + e.printStackTrace(); + } + return null; + + + + + + } + +} diff --git a/group04/349184132/Study/src/com/linked/Iterator.java b/group04/349184132/Study/src/com/linked/Iterator.java new file mode 100644 index 0000000000..b2397b9aa7 --- /dev/null +++ b/group04/349184132/Study/src/com/linked/Iterator.java @@ -0,0 +1,7 @@ +package com.linked; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group04/349184132/Study/src/com/linked/LinkedList.java b/group04/349184132/Study/src/com/linked/LinkedList.java new file mode 100644 index 0000000000..44aba236b4 --- /dev/null +++ b/group04/349184132/Study/src/com/linked/LinkedList.java @@ -0,0 +1,388 @@ +package com.linked; + +import java.util.Objects; + + + +public class LinkedList implements List { + + private Node head; + + private int size = 0; + + public LinkedList(){ + this.head = new Node(null,null); + } + + public boolean add(T o){ + + if(head.next == null){ + Node element = new Node(o,null); + head.next = element; + size++; + return true; + } + + Node current = head.next; + while(current != null){ + if(current.next==null){ + Node element = new Node(o,null); + current.next = element; + size++; + return true; + } + current = current.next; + } + + return false; + } + + + private void rangeCheck(int index) { + if (index < -1 || index > size - 1) + throw new IndexOutOfBoundsException(" index "); + } + public boolean add(int index , T o){ + rangeCheck(index); + + Node node = getNode(index); + Node pre = getNode(index-1); + Node newNode = new Node(o,node); + pre.next = newNode; + size++; + return true; + } + + + private Node getNode(int index){ + rangeCheck(index); + Node current = head.next; + int count = 0; + while(current!=null){ + if(count==index){ + return current; + } + count++; + current = current.next; + } + return null; + } + + public T get(int index){ + Node node = getNode(index); + return (T)node.data; + } + public T remove(int index){ + rangeCheck(index); + + Node pre = getNode(index-1); + Node cur = getNode(index); + Node next = cur.next; + pre.next = next; + cur.next = null; + size--; + return (T)cur.data; + } + + + public T remove(T o) { + int index = 0; + for (Node x = head.next; x != null; x = x.next) { + if (Objects.deepEquals(x.data, o)) { + return remove(index); + } + index++; + } + size--; + + return null; + } + + @Override + public T set(int index, T element) { + Node node = getNode(index); + node.data = element; + + return (T)node.data; + } + + @Override + public boolean contains(Object o) { + + return indexOf(o)!=-1; + } + + @Override + public int indexOf(Object o) { + int index = 0; + + for (Node x = head.next; x != null; x = x.next) { + if (Objects.deepEquals(x.data, o)) + return index; + index++; + } + return -1; + } + + @Override + public Object[] toArray() { + Object[] result = new Object[size]; + int i = 0; + for(Node x = head.next; x != null; x = x.next){ + result[i++] = x.data; + } + return null; + } + + @Override + public void clear() { + for(Node cur = head.next;cur!=null;cur = cur.next){ + Node x = cur; + x.data = null; + x.next = null; + } + head = null; + size = 0; + } + + + public int size(){ + return size; + } + public boolean isEmpty() { + return size == 0; + } + public void addFirst(Object o){ + Node newFirst = new Node(o,null); + Node oldFirst = head.next; + head.next = newFirst; + newFirst.next = oldFirst; + size++; + } + public void addLast(Object o){ + Node last = getNode(size-1); + Node newLast = new Node(o,null); + last.next = newLast; + size++; + } + public T removeFirst(){ + Node oldFirst = head.next; + Node nextNode = oldFirst.next; + head.next = nextNode; + size--; + return (T)oldFirst; + } + public T removeLast(){ + Node x = getNode(size-2);//倒数第二个结点 + Node last = x.next; + x.next = null; + size--; + return (T)last; + } + public Iterator iterator(){ + return new LinkedListIterator(); + } + + private class LinkedListIterator implements Iterator { + int pos = 0; + + @Override + public boolean hasNext() { + return pos < size; + } + + @Override + public Object next() { + if (pos > size) + throw new IllegalArgumentException(); + return get(pos++); + } + } + + + + private static class Node{ + Object data; + Node next; + private Node(Object data, Node next) { + this.data = data; + this.next = next; + + } + } + + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public Node reverseFor(Node head){ + if(head==null){ + return null; + } + Node pre = null; + Node curr = head; + Node next = head.next; + while(curr.next!=null){ + + head.next = pre; + pre = curr; + curr = curr.next; + next = next.next; + head = curr; + } + pre = null; + curr = null; + return head; + } + /** + * 递归写法 + * @param node + * @return + */ + public Node reverseRecursion(Node current){ + if(current == null || current.next == null){ + return current; + } + Node nextNode = current.next; + current = null; + Node reverseNode = reverseRecursion(current.next); + nextNode.next = current; + + + return reverseNode; + + } + + /** + * 删除一个单链表的前半部分 + * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + int delectLength = size/2; + for(int i=0;isize-length){ + throw new IllegalArgumentException(i +" or "+length +" error"); + } + for(int j=i;j101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list==null){ + throw new NullPointerException("List is null"); + } + int[] result = new int[list.size()]; + int index = 0; + for(Iterator iter = list.iterator();iter.hasNext();){ + int LinkIndex = (int)iter.next(); + result[index] = (int)get(LinkIndex); + } + return result; + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 从当前链表中中删除在list中出现的元素 + + * @param list + */ + + public void subtract(LinkedList list){ + if(list == null){ + throw new NullPointerException("List is null"); + } + int index = 0; + for(Node cur = head.next ; cur !=null ; cur = cur.next){ + for(Node newList = list.head.next ; newList != null; newList = newList.next ){ + if(Objects.deepEquals(cur.data, newList.data)){ + remove(index); + } + } + index++; + } + } + + /** + * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) + */ + public void removeDuplicateValues(){ + for(Node current=head.next;current!=null;current=current.next){ + Node nextNode = current.next; + + if(current.data.equals(nextNode.data)){ + Node nextNodeNext = nextNode.next; + if(nextNodeNext==null){ + current.next = null; + }else{ + current.next = nextNodeNext; + nextNode.next = null; + } + } + } + } + + /** + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 + * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * @param min + * @param max + */ + public void removeRange(int min, int max) { + if (min + max > size && min == max) { + throw new IndexOutOfBoundsException("Arguement is Illegal"); + } + int index = 0; + for (Node curr = head.next; curr != null; curr = curr.next) { + if(((int)curr.data>min) && ((int)curr.data { + public boolean add(T o); + + public boolean add(int index, T o); + + public T get(int index); + + T set(int index, T element); + + public T remove(int index); + + public T remove(T o); + + public int size(); + + public boolean isEmpty(); + + public Iterator iterator(); + + public boolean contains(Object o); + + int indexOf(Object o); + + + Object[] toArray(); + + void clear(); + +} diff --git a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java index 06944cd8b1..4acbbf8880 100644 --- a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java +++ b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java @@ -64,7 +64,7 @@ public void testFibonacci() { public void testGetPrimes() { int[] primes = {2,3,5,7,11,13,17,19}; int max = 23; - Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(max)); + Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(27)); } @Test diff --git a/group04/351121278/src/com/coding/download/DownloadThread.java b/group04/351121278/src/com/coding/download/DownloadThread.java new file mode 100644 index 0000000000..e0b396a5e6 --- /dev/null +++ b/group04/351121278/src/com/coding/download/DownloadThread.java @@ -0,0 +1,34 @@ +package com.coding.download; + +import com.coding.download.api.Connection; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + File file; + + public DownloadThread(File file, Connection conn, int startPos, int endPos){ + this.file = file; + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + } + public void run(){ + try { + System.out.println("DownloadThread.run"); + byte[] buffer = conn.read(startPos, endPos); + RandomAccessFile raf = new RandomAccessFile(file, "rw"); + raf.seek(startPos); + raf.write(buffer, 0, buffer.length); + raf.close(); + } catch (IOException e) { + System.out.println("e = " + e.getMessage()); + } + } +} diff --git a/group04/351121278/src/com/coding/download/FileDownloader.java b/group04/351121278/src/com/coding/download/FileDownloader.java new file mode 100644 index 0000000000..13d24f5b2b --- /dev/null +++ b/group04/351121278/src/com/coding/download/FileDownloader.java @@ -0,0 +1,76 @@ +package com.coding.download; + + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; + +import java.io.File; + +public class FileDownloader { + + String url; + + DownloadListener listener; + + ConnectionManager cm; + + + public FileDownloader(String _url) { + this.url = _url; + + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + Connection conn = null; + try { + + conn = cm.open(this.url); + File file = new File("D:/test"); + int length = conn.getContentLength(); + for (int i=0; i<3; i++) { + new DownloadThread(file, conn, 0, length-1).start(); + } + + } catch (ConnectionException e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + + + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} diff --git a/group04/351121278/src/com/coding/download/FileDownloaderTest.java b/group04/351121278/src/com/coding/download/FileDownloaderTest.java new file mode 100644 index 0000000000..84fbc8afa2 --- /dev/null +++ b/group04/351121278/src/com/coding/download/FileDownloaderTest.java @@ -0,0 +1,59 @@ +package com.coding.download; + +import com.coding.download.api.ConnectionManager; +import com.coding.download.api.DownloadListener; +import com.coding.download.impl.ConnectionManagerImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class FileDownloaderTest { + boolean downloadFinished = false; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url = "http://localhost:8080/test.jpg"; + + FileDownloader downloader = new FileDownloader(url); + + + ConnectionManager cm = new ConnectionManagerImpl(); + downloader.setConnectionManager(cm); + + downloader.setListener(new DownloadListener() { + @Override + public void notifyFinished() { + downloadFinished = true; + } + + }); + + + downloader.execute(); + + // 等待多线程下载程序执行完毕 + while (!downloadFinished) { + try { + System.out.println("还没有下载完成,休眠五秒"); + //休眠5秒 + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + +} diff --git a/group04/351121278/src/com/coding/download/api/Connection.java b/group04/351121278/src/com/coding/download/api/Connection.java new file mode 100644 index 0000000000..bd75d6cad0 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coding.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos, int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group04/351121278/src/com/coding/download/api/ConnectionException.java b/group04/351121278/src/com/coding/download/api/ConnectionException.java new file mode 100644 index 0000000000..1f57f86606 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/ConnectionException.java @@ -0,0 +1,10 @@ +package com.coding.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(String exceptionMessage) { + + } + public ConnectionException() { + } +} diff --git a/group04/351121278/src/com/coding/download/api/ConnectionManager.java b/group04/351121278/src/com/coding/download/api/ConnectionManager.java new file mode 100644 index 0000000000..1d1a83caf2 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coding.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; +} diff --git a/group04/351121278/src/com/coding/download/api/DownloadListener.java b/group04/351121278/src/com/coding/download/api/DownloadListener.java new file mode 100644 index 0000000000..c41045b0e8 --- /dev/null +++ b/group04/351121278/src/com/coding/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coding.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..7d524ec4a0 --- /dev/null +++ b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java @@ -0,0 +1,50 @@ +package com.coding.download.impl; + +import com.coding.download.api.Connection; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + + +public class ConnectionImpl implements Connection { + + private static final int THEAD_COUNT = 3; + private URL url; + private HttpURLConnection httpURLConnection; + private final int BUFFER_SIZE = 1024; + + public ConnectionImpl(URL url) { + this.url = url; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + URLConnection urlConnection = url.openConnection(); + httpURLConnection = (HttpURLConnection)urlConnection; + httpURLConnection.setRequestMethod("GET"); + InputStream in = httpURLConnection.getInputStream(); + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + int len; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((len = in.read(buffer)) != -1) { + byteOutputStream.write(buffer, startPos, len); + } + return byteOutputStream.toByteArray(); + } + + @Override + public int getContentLength() { + return httpURLConnection.getContentLength(); + } + + @Override + public void close() { + httpURLConnection.disconnect(); + } + +} diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..c07a0b545a --- /dev/null +++ b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,23 @@ +package com.coding.download.impl; + +import com.coding.download.api.Connection; +import com.coding.download.api.ConnectionException; +import com.coding.download.api.ConnectionManager; + +import java.net.MalformedURLException; +import java.net.URL; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + URL urlObj; + try { + urlObj = new URL(url); + } catch (MalformedURLException e) { + throw new ConnectionException("URL无法访问" + e.getMessage()); + } + return new ConnectionImpl(urlObj); + } + +} diff --git a/group04/474772605/.classpath b/group04/474772605/.classpath index 28e2b79383..8d7ead9fe8 100644 --- a/group04/474772605/.classpath +++ b/group04/474772605/.classpath @@ -1,7 +1,11 @@ + + + + diff --git a/group04/474772605/jsp/homepage.jsp b/group04/474772605/jsp/homepage.jsp new file mode 100644 index 0000000000..83fa84db7d --- /dev/null +++ b/group04/474772605/jsp/homepage.jsp @@ -0,0 +1,12 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + + +homepage + + + + + \ No newline at end of file diff --git a/group04/474772605/jsp/showLogin.jsp b/group04/474772605/jsp/showLogin.jsp new file mode 100644 index 0000000000..1e6cda01b1 --- /dev/null +++ b/group04/474772605/jsp/showLogin.jsp @@ -0,0 +1,12 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + + +showLogin + + + + + \ No newline at end of file diff --git a/group12/382266293/src/com/coderising/action/LoginAction.java b/group04/474772605/src/com/coderising/action/LoginAction.java similarity index 95% rename from group12/382266293/src/com/coderising/action/LoginAction.java rename to group04/474772605/src/com/coderising/action/LoginAction.java index b1224eb80d..69ad2750c0 100644 --- a/group12/382266293/src/com/coderising/action/LoginAction.java +++ b/group04/474772605/src/com/coderising/action/LoginAction.java @@ -1,39 +1,40 @@ -package com.coderising.action; - -/** - * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @author liuxin - * - */ -public class LoginAction{ - private String name ; - private String password; - private String message; - - public String getName() { - return name; - } - - public String getPassword() { - return password; - } - - public String execute(){ - if("test".equals(name) && "1234".equals(password)){ - this.message = "login successful"; - return "success"; - } - this.message = "login failed,please check your user/pwd"; - return "fail"; - } - - public void setName(String name){ - this.name = name; - } - public void setPassword(String password){ - this.password = password; - } - public String getMessage(){ - return this.message; - } -} \ No newline at end of file +package com.coderising.action; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LoginAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/474772605/src/com/coderising/action/LogoutAction.java b/group04/474772605/src/com/coderising/action/LogoutAction.java new file mode 100644 index 0000000000..10e4eb37c7 --- /dev/null +++ b/group04/474772605/src/com/coderising/action/LogoutAction.java @@ -0,0 +1,40 @@ +package com.coderising.action; + +/** + * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 + * @author liuxin + * + */ +public class LogoutAction{ + private String name ; + private String password; + private String message; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String execute(){ + if("test".equals(name) && "1234".equals(password)){ + this.message = "login successful"; + return "success1"; + } + this.message = "login failed,please check your user/pwd"; + return "fail"; + } + + public void setName(String name){ + + this.name = name; + } + public void setPassword(String password){ + this.password = password; + } + public String getMessage(){ + return this.message; + } +} diff --git a/group04/474772605/src/com/coderising/action/Struts.java b/group04/474772605/src/com/coderising/action/Struts.java new file mode 100644 index 0000000000..7db0e4687f --- /dev/null +++ b/group04/474772605/src/com/coderising/action/Struts.java @@ -0,0 +1,122 @@ +package com.coderising.action; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.dom4j.Attribute; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + + + +public class Struts { + + + + public static void main(String[] args) throws DocumentException { + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + View view = Struts.runAction(actionName,params); + System.out.println(view.getJsp()); + System.out.println(view.getParameters()); + } + + + public static View runAction(String actionName, Map parameters) { + View view = new View(); + SAXReader reader = new SAXReader(); + //读取文件 转换成Document + org.dom4j.Document document; + try { + document = reader.read(new File("src/struts.xml")); + Element root = document.getRootElement(); + @SuppressWarnings("unchecked") + List elements = root.elements(); + for (Element element : elements) { + Attribute actionAttribute = element.attribute("name"); + Attribute classAttribute = element.attribute("class"); + if(actionName.equals(actionAttribute.getValue())){ + String clazz = null; + clazz = classAttribute.getValue(); + Object o = Class.forName(clazz).newInstance(); + for (Map.Entry entry : parameters.entrySet()) { + String name = entry.getKey(); + String value =entry.getValue(); + String methodname = "set"+name.substring(0,1).toUpperCase()+name.substring(1); + Method m = o.getClass().getMethod(methodname, String.class); + m.invoke(o, value); + + } + Method m3 = o.getClass().getMethod("execute"); + String result = (String) m3.invoke(o); + String jspPath = null; + List element1s = element.elements("result"); + if(result.equals("success")){ + for (int i = 0; i < element1s.size(); i++) { + Attribute attribute2 = element1s.get(i).attribute("name"); + if (attribute2.getValue().equals("success")) { + jspPath = element1s.get(i).getStringValue(); + } + } + }else if(result.equals("fail")){ + for (int i = 0; i < element1s.size(); i++) { + Attribute attribute2 = element1s.get(i).attribute("name"); + if (attribute2.getValue().equals("fail")) { + jspPath = element1s.get(i).getStringValue(); + } + } + } + HashMapviewparamterHashMap = new HashMap(); + Method[]methods = o.getClass().getMethods(); + String methodname; + for (int j = 0; j < o.getClass().getMethods().length; j++) { + methodname = methods[j].getName(); + if(methodname.startsWith("get")&&!methodname.equals("getClass")){ + String methodname1 = methods[j].getName(); + methodname1 = methodname.substring(3,4).toUpperCase()+methodname1.substring(4); + viewparamterHashMap.put(methodname1, methods[j].invoke(o)); + } + } + view.setJsp(jspPath); + view.setParameters(viewparamterHashMap); + return view; + } + } + } catch (Exception e) { + // TODO: handle exception + } + return null; + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + } + +} diff --git a/group04/474772605/src/com/coderising/action/StrutsTest.java b/group04/474772605/src/com/coderising/action/StrutsTest.java new file mode 100644 index 0000000000..c161c0f932 --- /dev/null +++ b/group04/474772605/src/com/coderising/action/StrutsTest.java @@ -0,0 +1,43 @@ +package com.coderising.action; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "com.coderising.action.LoginAction"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group04/474772605/src/com/coderising/action/View.java b/group04/474772605/src/com/coderising/action/View.java new file mode 100644 index 0000000000..11cb1872e5 --- /dev/null +++ b/group04/474772605/src/com/coderising/action/View.java @@ -0,0 +1,23 @@ +package com.coderising.action; + +import java.util.Map; + +public class View { + private String jsp; + private Map parameters; + + public String getJsp() { + return jsp; + } + public View setJsp(String jsp) { + this.jsp = jsp; + return this; + } + public Map getParameters() { + return parameters; + } + public View setParameters(Map parameters) { + this.parameters = parameters; + return this; + } +} diff --git a/group04/474772605/src/com/coderising/action/struts.xml b/group04/474772605/src/com/coderising/action/struts.xml new file mode 100644 index 0000000000..a6cfe43e6c --- /dev/null +++ b/group04/474772605/src/com/coderising/action/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + \ No newline at end of file diff --git a/group04/474772605/src/com/coderising/array/ArrayUtil.java b/group04/474772605/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..ddb00c17b6 --- /dev/null +++ b/group04/474772605/src/com/coderising/array/ArrayUtil.java @@ -0,0 +1,146 @@ +package com.coderising.array; + +import java.util.ArrayList; +import java.util.Stack; + +import com.coding.basic.LinkedList; + +public class ArrayUtil { + + /** + * 给定一个整形数组a , 对该数组的值进行置换 + 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] + 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] + * @param origin + * @return + */ + public void reverseArray(int[] origin){ + Stack stack = new Stack(); + for (int i = 0; i < origin.length; i++) { + stack.add(origin[i]); + } + + for (int j = 0; j < stack.size(); j++) { + origin[j] = (Integer) stack.pop(); + } + + } + + /** + * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} + * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: + * {1,3,4,5,6,6,5,4,7,6,7,5} + * @param oldArray + * @return + */ + + public int[] removeZero(int[] oldArray){ + ArrayList newarray = new ArrayList(); + for (int i = 0; i < oldArray.length; i++) { + if(0!=oldArray[i]){ + newarray.add(oldArray[i]); + } + } + int result [] = new int [newarray.size()]; + for (int j = 0; j < result.length; j++) { + result[j]=newarray.get(j); + } + + return result; + } + + /** + * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 + * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 + * @param array1 + * @param array2 + * @return + */ + + public int[] merge(int[] array1, int[] array2){ + ArrayList newarray = new ArrayList(); + for (int i = 0; i < array1.length; i++) { + newarray.add(i, array1[i]); + } + for (int j = 0; j < array2.length; j++) { + if (newarray.get(j)>array2[j]&&newarray.get(j+1)>array2[j]) { + newarray.add(j+1, array2[j]); + } + } + + int result [] = new int [newarray.size()]; + for (int z = 0; z < result.length; z++) { + result[z]=newarray.get(z); + } + return result; + } + /** + * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size + * 注意,老数组的元素在新数组中需要保持 + * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 + * [2,3,6,0,0,0] + * @param oldArray + * @param size + * @return + */ + public int[] grow(int [] oldArray, int size){ + ArrayList newarray = new ArrayList(); + for (int i = 0; i < oldArray.length; i++) { + newarray.add(i, oldArray[i]); + } + while (newarray.size()='A'&&(char)num <='z'){ + n1++; + } + if((char)num >='A'&&(char)num <='Z'){ + n2++; + } + } + } + reader.close(); + System.out.println(n1+""+n2); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + + + public float method(){ + return 13.21f; + } + + + + + } + + + + + + + + + + + diff --git a/group04/474772605/src/com/coding/iostreams/test.java b/group04/474772605/src/com/coding/iostreams/test.java new file mode 100644 index 0000000000..1bd474ca7b --- /dev/null +++ b/group04/474772605/src/com/coding/iostreams/test.java @@ -0,0 +1,14 @@ +package com.coding.iostreams; + +public interface test { + public float method(); + +} + + + + + + + + diff --git a/group04/349184132/Study/bin/com/second/struts.xml b/group04/474772605/src/struts.xml similarity index 57% rename from group04/349184132/Study/bin/com/second/struts.xml rename to group04/474772605/src/struts.xml index 554dbbe227..8bd00bb1f0 100644 --- a/group04/349184132/Study/bin/com/second/struts.xml +++ b/group04/474772605/src/struts.xml @@ -1,11 +1,11 @@ - + /jsp/homepage.jsp /jsp/showLogin.jsp - + /jsp/welcome.jsp - /jsp/error.jsp + /jsp/error.jsp \ No newline at end of file diff --git a/group04/474772605/test/Test.java b/group04/474772605/test/Test.java new file mode 100644 index 0000000000..8c0f62930b --- /dev/null +++ b/group04/474772605/test/Test.java @@ -0,0 +1,50 @@ + + + import java.io.File; + import java.io.FileInputStream; + import java.io.InputStreamReader; + import java.io.Reader; + + + + + public class Test{ + static int n1 =0 ; + static int n2 =0 ; + + public static void main(String[] args) throws Exception{ + + Test.readFileByChars("D://Text.txt"); + + System.out.println("字母个数为:"+n1+" 字母个数为"+n2); + + } + + public static void readFileByChars(String fileName) { + File file = new File(fileName); + Reader reader = null; + try { + System.out.println("以字符为单位读取文件内容,一次读一个字节:"); + // 一次读一个字符 + reader = new InputStreamReader(new FileInputStream(file)); + int tempchar; + while ((tempchar = reader.read()) != -1) { + // 对于windows下,\r\n这两个字符在一起时,表示一个换行。 + // 但如果这两个字符分开显示时,会换两次行。 + // 因此,屏蔽掉\r,或者屏蔽\n。否则,将会多出很多空行。 + if (((char) tempchar) != '\r') { + System.out.print((char) tempchar); + n1++; + if((char)tempchar >='A'&&(char)tempchar<='Z'){ + n2++; + } + + } + } + reader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + diff --git a/group04/474772605/test/com/coding/basic/Heros.java b/group04/474772605/test/com/coding/basic/Heros.java new file mode 100644 index 0000000000..878204aede --- /dev/null +++ b/group04/474772605/test/com/coding/basic/Heros.java @@ -0,0 +1,51 @@ +package com.coding.basic; + +import java.lang.reflect.Method; + +public class Heros { + private String name;//名字 + private String type;//类型 + private int camp;//0,近卫;1,天灾 + public Heros(){ + + } + /* + public Heros(String name, String type, int camp) { + + super(); + + this.name = name; + this.type = type; + this.camp = camp; + }*/ + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getCamp() { + return camp; + } + + public void setCamp(int camp) { + this.camp = camp; + } + + @Override + public String toString() { + return "Heros [\n name=" + name + ", \n type=" + type + ", \n camp=" + camp + "\n]"; + } + +} \ No newline at end of file diff --git a/group04/474772605/test/com/coding/basic/Test.java b/group04/474772605/test/com/coding/basic/Test.java new file mode 100644 index 0000000000..97f7254c82 --- /dev/null +++ b/group04/474772605/test/com/coding/basic/Test.java @@ -0,0 +1,43 @@ +package com.coding.basic; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class Test { + + public static void main(String args[]) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Foo foo = new Foo("这个一个Foo对象!"); + Class clazz = foo.getClass(); + Field[] abc =clazz.getDeclaredFields(); + + // Object value = getFieldValueByName(key, obj);  + Method m1 = clazz.getDeclaredMethod("outInfo"); + Method m2 = clazz.getDeclaredMethod("setMsg", String.class); + Method m3 = clazz.getDeclaredMethod("getMsg"); + m1.invoke(foo); + m2.invoke(foo, "重新设置msg信息!"); + String msg = (String) m3.invoke(foo); + System.out.println(msg); + } +} + +class Foo { + private String msg; + + public Foo(String msg) { + this.msg = msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void outInfo() { + System.out.println("这是测试Java反射的测试类"); + } +} diff --git a/group04/474772605/test/com/coding/basic/TestStack.java b/group04/474772605/test/com/coding/basic/TestStack.java new file mode 100644 index 0000000000..e4caa84d98 --- /dev/null +++ b/group04/474772605/test/com/coding/basic/TestStack.java @@ -0,0 +1,35 @@ +package com.coding.basic; + +import junit.framework.TestCase; + +public class TestStack extends TestCase{ +private Stack stack; + + +public void setUp() throws Exception { + stack = new Stack(); + +} + +public void testpop(){ +// Stack stack = new Stack(); + Object o = null ; + try { + stack.push(o); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + +} + + + + + + + +} diff --git a/group04/474772605/test/com/coding/basic/Testarray.java b/group04/474772605/test/com/coding/basic/Testarray.java new file mode 100644 index 0000000000..19edb9f85d --- /dev/null +++ b/group04/474772605/test/com/coding/basic/Testarray.java @@ -0,0 +1,22 @@ +package com.coding.basic; + +import junit.framework.TestCase; + +public class Testarray extends TestCase{ + + public void testararry(){ + Throwable tx = null; + try { + ArrayList n = new ArrayList(); + Object o = null ; + + n.add(o); + fail(); + } catch (Exception e) { + tx =e; + assertEquals(Exception.class, tx.getClass()); + assertEquals("对象不能为空", e.getMessage()); + } + } + +} diff --git a/group04/474772605/test/com/coding/basic/teest.java b/group04/474772605/test/com/coding/basic/teest.java new file mode 100644 index 0000000000..e8004c14b6 --- /dev/null +++ b/group04/474772605/test/com/coding/basic/teest.java @@ -0,0 +1,24 @@ +package com.coding.basic; + +import java.lang.reflect.Method; + +public class teest { + public static void main(String[] args) { + Class herosClass = Heros.class; + try { + Method m1 = herosClass.getMethod("setName",String.class); + Method m3 = herosClass.getMethod("setCamp",int.class); + Method m2 = herosClass.getMethod("getName"); + + + Object userInfo = herosClass.newInstance(); + System.out.println("调用构造函数:"+userInfo); + m1.invoke(userInfo,"影魔"); + m3.invoke(userInfo, 1); + System.out.println("调用set方法:"+userInfo); + System.out.println("调用get方法:"+m2.invoke(userInfo)); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..d4e0f52537 --- /dev/null +++ b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,83 @@ +package com.coderising.jvm.loader; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + + + +public class ClassFileLoader { + + private static final String CLASS_SUFFIX = ".class"; + private static final byte[] EMPTY_BYTES = new byte[0]; + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + if(StringUtils.isEmpty(className)) { + return EMPTY_BYTES; + } + String child = className.replaceAll("\\.", "\\\\") + CLASS_SUFFIX; + for (String parent: clzPaths) { + File file = new File(parent, child); + if(file.exists()) { + return doReadBinaryCode(file); + } + } + return EMPTY_BYTES; + } + + + private byte[] doReadBinaryCode(File file) { + FileInputStream fis = null; + ByteArrayOutputStream baos = null; + try { + fis = new FileInputStream(file); + baos = new ByteArrayOutputStream(); + byte[] b = new byte[1024]; + int len = 0; + while((len = fis.read(b)) > 0) { + baos.write(b, 0, len); + } + return baos.toByteArray(); + } catch (Exception e) { + new RuntimeException(e); + } finally { + close(baos); + close(fis); + } + return EMPTY_BYTES; + } + + + private void close(Closeable stream) { + if(stream != null ) { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void addClassPath(String path) { + clzPaths.add(path); + } + + public String getClassPath(){ + StringBuilder builder = new StringBuilder(); + for (String path : clzPaths) { + builder.append(path).append(";"); + } + if(builder.length() > 0) { + builder = builder.deleteCharAt(builder.length() - 1); + } + return builder.toString(); + } + +} diff --git a/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..3f4a585db7 --- /dev/null +++ b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,93 @@ +package com.coderising.jvm.test; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.coderising.jvm.loader.ClassFileLoader; + + + + + +public class ClassFileloaderTest { + + + private static final String CAFEBABE = "cafebabe"; + static String path1 = "D:\\Dev\\git_repository\\coding2017\\group04\\498654356\\mini-jvm\\jvm\\target\\test-classes"; + static String path2 = "C:\\temp"; + + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath(){ + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1+";"+path2,clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "com.coderising.jvm.test.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1056, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.coderising.jvm.test.EmployeeV1"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals(CAFEBABE, acctualValue); + } + + + + + + + private String byteToHexString(byte[] codes ){ + StringBuffer buffer = new StringBuffer(); + for(int i=0;i size) { + return Arrays.copyOf(baos.toByteArray(), size); + } + return baos.toByteArray(); + } + + @Override + public int getContentLength() { + try { + return url.openConnection().getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void close() { + try { + url.openStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..e595cb3ccb --- /dev/null +++ b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,14 @@ +package org.coding.three.download.impl; + +import org.coding.three.download.api.Connection; +import org.coding.three.download.api.ConnectionException; +import org.coding.three.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + return new ConnectionImpl(url); + } + +} diff --git a/group04/498654356/one/src/org/coding/three/list/List.java b/group04/498654356/one/src/org/coding/three/list/List.java new file mode 100644 index 0000000000..d06cf962da --- /dev/null +++ b/group04/498654356/one/src/org/coding/three/list/List.java @@ -0,0 +1,9 @@ +package org.coding.three.list; + +public interface List { + public void add(Object o); + public void add(int index, Object o); + public Object get(int index); + public Object remove(int index); + public int size(); +} diff --git a/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java new file mode 100644 index 0000000000..ef38ca811d --- /dev/null +++ b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java @@ -0,0 +1,422 @@ +package org.coding.three.list.impl; + +import java.util.Arrays; +import java.util.Iterator; + +import org.coding.three.list.List; +/** + * 单链表/单向链表 + */ +public class LinkedList implements List { + /** + * 0. head 节点存储数据 + * 1. 这里的 head 第一次添加之后 "引用" 将不再改变;"值" 可以被修改已表示往首节点插入新的值。 + * 2. 可以将 head 修改为对 node 引用, 不存储任何数据。 + */ + private Node head; + + public void add(Object o){ + Node node = new Node(o); + if(head == null){ //第一次 + head = node; + } else { + getNode(size() - 1).next = node; + } + } + + private Node getNode(int index) { + checkIndex(index); + Node node = head; + for(int i = 0; i < index; i++) { + node = node.next; + } + return node; + } + + private void checkIndex(int index) { + int size = size(); + if(index < 0 || index > (size - 1)) { + throw new IndexOutOfBoundsException("size = " + size + ", index = " + index); + } + } + public void add(int index , Object o){ + checkIndex(index); + if(index == 0) { //更新 head 的值, 将旧值创建新的Node插入到 head 后 + Object data = head.data; + head.data = o; + Node node = new Node(data); + node.next = head.next; + head.next = node; + } else { + Node pre = getNode(index - 1); + Node node = new Node(o); + node.next = pre.next; + pre.next = node; + } + } + public Object get(int index){ + checkIndex(index); + return getNode(index).data; + } + public Object remove(int index){ + checkIndex(index); + Object data = null; + if(index == 0) { + Node next = head.next; + data = head.data; + if(next == null) { + head = null; + } else { + head.data = next.data; + head.next = next.next; + next.next = null; + } + } else { + Node pre = getNode(index - 1); + Node node = pre.next; + pre.next = node.next; + node.next = null; + data = node.data; + } + return data; + } + + public int size(){ + Node temp = head; + int size = 0; + while(temp != null) { + size++; + temp = temp.next; + } + return size; + } + + public void addFirst(Object o){ + add(0, o); + } + public void addLast(Object o){ + add(o); + } + public Object removeFirst(){ + return remove(0); + } + public Object removeLast(){ + return remove(size() - 1); + } + public Iterator iterator(){ + return new LinkedIterator(); + } + + class LinkedIterator implements Iterator { + 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..0d08db77e9 --- /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..63d98a4636 --- /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..88a8bdf9b3 --- /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..c1c4bc9032 --- /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..d1c189316b --- /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..be1fbff668 --- /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..cd390c9296 --- /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..f4f05269df --- /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..0b3167cd90 --- /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..4cd0b3eab1 --- /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..4d6fbc4b87 --- /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..68a5b7a7fc --- /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..ee70db2150 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,119 +1,122 @@ -package com.coding.basic; - -/** - * @ClassName: ArrayList - * @Description: 自增长数组 - * @author: tangxp - * @date: 2017年2月23日 下午10:43:03 - */ -public class ArrayList implements List { - - private final int step = 10; - private Object elementData[] = new Object[100]; - private int size = 0 ; - - - /** - * @Title: add - * @Description: TODO - * @param o , elements of this ArrayList - * @see com.coding.basic.List#add(java.lang.Object) - */ - public void add(Object o) { - add(size,o); - } - - - /** - * @Title: add - * @Description: TODO - * @param index - * @param o - * @see com.coding.basic.List#add(int, java.lang.Object) - */ - public void add(int index, Object o) { - if(index < 0 || index> size) { - throw new IllegalArgumentException("下标越界"); - } - - if(null == o) { - throw new IllegalArgumentException("元素不能为空"); - } - - if(this.checkOutOfBounds()) { - this.autoGrow(this.step); - } - - int i = size; - while(i>index) { - elementData[i] = elementData[--i]; - } - addDriect(i, o); - } - - - public Object get(int index) { - if(index < 0 || index>= size) { - throw new IllegalArgumentException("下标越界"); - } - - return elementData[index]; - } - - public Object remove(int index) { - if(index < 0 || index>= size) { - throw new IllegalArgumentException("下标越界"); - } - - Object o = elementData[index]; - while (indexthis.size) { - return; - } - Object newElementData[] = new Object[elementData.length+growSize]; - System.arraycopy(elementData, 0, newElementData, 0, elementData.length); - elementData = newElementData; - return; - } - - private void addDriect(int index, Object o) { - elementData[index] = o; - this.size++; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("["); - for(int i =0;ithis.size) { - return false; - }else { - return true; - } - } -} +package com.coding.basic; + +import java.util.concurrent.CyclicBarrier; + +/** + * @ClassName: ArrayList + * @Description: 自增长数组 + * @author: tangxp + * @date: 2017年2月23日 下午10:43:03 + */ +public class ArrayList implements List { + + private final int step = 10; + private Object elementData[] = new Object[100]; + private int size = 0 ; + + + /** + * @Title: add + * @Description: TODO + * @param o , elements of this ArrayList + * @see com.coding.basic.List#add(java.lang.Object) + */ + public void add(Object o) { + add(size,o); + } + + + /** + * @Title: add + * @Description: TODO + * @param index + * @param o + * @see com.coding.basic.List#add(int, java.lang.Object) + */ + public void add(int index, Object o) { + if(index < 0 || index> size) { + throw new IllegalArgumentException("下标越界"); + } + + if(null == o) { + throw new IllegalArgumentException("元素不能为空"); + } + + if(this.checkOutOfBounds()) { + this.autoGrow(this.step); + } + + int i = size; + while(i>index) { + elementData[i] = elementData[--i]; + } + addDriect(i, o); + } + + + public Object get(int index) { + if(index < 0 || index>= size) { + throw new IllegalArgumentException("下标越界"); + } + + return elementData[index]; + } + + public Object remove(int index) { + if(index < 0 || index>= size) { + throw new IllegalArgumentException("下标越界"); + } + + Object o = elementData[index]; + while (indexthis.size) { + return; + } + Object newElementData[] = new Object[elementData.length+growSize]; + System.arraycopy(elementData, 0, newElementData, 0, elementData.length); + elementData = newElementData; + return; + } + + private void addDriect(int index, Object o) { + elementData[index] = o; + this.size++; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("["); + for(int i =0;ithis.size) { + return false; + }else { + 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..cad618d536 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,134 +1,349 @@ -package com.coding.basic; - - -/** - * @ClassName: LinkedList - * @Description: 带头结点的单向列表. - * @author: tangxp - * @date: 2017年2月23日 下午9:14:28 - */ -public class LinkedList implements List { - - private Node head = new Node(); - private int size ; - - public void add(Object o){ - add(size,o); - } - - public void add(int index , Object o){ - if(index<0 || index>size) { - throw new IllegalArgumentException("目前链表长度不够!"); - } - Node tempHead = head; - int i = 0; - while(i++ < index) { - tempHead = tempHead.next; - } - addDriect(getNode(o),tempHead); - } - - - /** - * @Title: get - * @Description: TODO - * @param index - * @return - * @see com.coding.basic.List#get(int) - */ - public Object get(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.data; - } - - public Object remove(int index){ - if(index<0 || index>=size) { - throw new IllegalArgumentException("下标超出链表范围!"); - } - Node tempHead = head; - int i = 0; - while(i++ < index) { - tempHead = tempHead.next; - } - - Node removingNode = tempHead.next; - tempHead.next = removingNode.next; - removingNode.next = null; - size--; - return removingNode.data; - } - - public int size(){ - 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 null; - } - - private void addDriect(Node n,Node before) { - Node temp = before.next; - n.next = temp; - before.next = n; - size++; - } - - private Node getNode(Object o) { - - if(null == o) { - throw new IllegalArgumentException("节点值不能为空"); - } - - Node n = new Node(); - n.data = o; - return n; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("size: "+size+" {null | ---}--->"); - if(null == head.next) { - return sb.toString(); - } - - Node tempHead = head; - while(null != tempHead.next ) { - sb.append(tempHead.next.toString()); - tempHead = tempHead.next; - } - sb.append("null"); - return sb.toString(); - } - - private static class Node{ - Object data; - Node next; - - @Override - public String toString() { - return "{" + this.data +" |---}--->"; - } - - } -} +package com.coding.basic; + +import java.util.concurrent.CyclicBarrier; + + +/** + * @ClassName: LinkedList + * @Description: 带头结点的单向列表. + * @author: tangxp + * @date: 2017年2月23日 下午9:14:28 + */ +public class LinkedList implements List { + + private Node head = new Node(); + private int size ; + + public void add(Object o){ + add(size,o); + } + + public void add(int index , Object o){ + if(index<0 || index>size) { + throw new IllegalArgumentException("目前链表长度不够!"); + } + Node tempHead = head; + int i = 0; + while(i++ < index) { + tempHead = tempHead.next; + } + addDriect(getNode(o),tempHead); + } + + + /** + * @Title: get + * @Description: TODO + * @param index + * @return + * @see com.coding.basic.List#get(int) + */ + public Object get(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.data; + } + + public Object remove(int index){ + if(index<0 || index>=size) { + throw new IllegalArgumentException("下标超出链表范围!"); + } + Node tempHead = head; + int i = 0; + while(i++ < index) { + tempHead = tempHead.next; + } + + Node removingNode = tempHead.next; + tempHead.next = removingNode.next; + removingNode.next = null; + size--; + return removingNode.data; + } + + public int size(){ + 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 null; + } + + private void addDriect(Node n,Node before) { + Node temp = before.next; + n.next = temp; + before.next = n; + size++; + } + + private Node getNode(Object o) { + + if(null == o) { + throw new IllegalArgumentException("节点值不能为空"); + } + + Node n = new Node(); + n.data = o; + return n; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("size: "+size+" {null | ---}--->"); + if(null == head.next) { + return sb.toString(); + } + + Node tempHead = head; + while(null != tempHead.next ) { + sb.append(tempHead.next.toString()); + tempHead = tempHead.next; + } + sb.append("null"); + return sb.toString(); + } + + private static class Node{ + Object data; + Node next; + + @Override + 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 - + - diff --git a/group04/844028312/three/.gitignore b/group04/844028312/three/.gitignore new file mode 100644 index 0000000000..ae3c172604 --- /dev/null +++ b/group04/844028312/three/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/group04/844028312/three/.project b/group04/844028312/three/.project new file mode 100644 index 0000000000..64a356de63 --- /dev/null +++ b/group04/844028312/three/.project @@ -0,0 +1,17 @@ + + + coding2017 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs b/group04/844028312/three/.settings/org.eclipse.jdt.core.prefs similarity index 78% rename from group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs rename to group04/844028312/three/.settings/org.eclipse.jdt.core.prefs index a698e59674..d17b6724d1 100644 --- a/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs +++ b/group04/844028312/three/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,12 @@ 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.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 +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.8 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/group04/844028312/three/src/com/coderising/array/ArrayUtil.java b/group04/844028312/three/src/com/coderising/array/ArrayUtil.java new file mode 100644 index 0000000000..e5ddb476a6 --- /dev/null +++ b/group04/844028312/three/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/844028312/three/src/com/coderising/download/DownloadThread.java b/group04/844028312/three/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..580da85576 --- /dev/null +++ b/group04/844028312/three/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,48 @@ +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 java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.impl.ConnectionManagerImpl; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + CyclicBarrier barrier; + String url; + public DownloadThread(CyclicBarrier barrier, String url, int startPos, int endPos){ + this.barrier=barrier; + //this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.url=url; + } + public void run(){ + try { + ConnectionManager cm = new ConnectionManagerImpl(); + conn=cm.open(url); + + byte[] b=conn.read(startPos, endPos); + + RandomAccessFile randomFile = new RandomAccessFile("D://test.zip", "rw"); + write(randomFile,b); + barrier.await(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + public synchronized void write(RandomAccessFile randomFile ,byte[] b) throws IOException{ + randomFile.seek(startPos); + randomFile.write(b); + randomFile.close(); + } +} diff --git a/group04/844028312/three/src/com/coderising/download/FileDownloader.java b/group04/844028312/three/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..9d81ef03be --- /dev/null +++ b/group04/844028312/three/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,86 @@ +package com.coderising.download; + +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 { + + 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 { + + + CyclicBarrier cb = new CyclicBarrier(4, new Runnable() { + @Override + public void run() { + // TODO Auto-generated method stub + listener.notifyFinished(); + + } + }); + conn=cm.open(url); + int length = conn.getContentLength(); + new DownloadThread(cb,url,0,length/4).start(); + new DownloadThread(cb,url,length/4+1,(length/4)*2).start(); + new DownloadThread(cb,url,(length/4)*2+1,(length/4)*3).start(); + new DownloadThread(cb,url,(length/4)*3+1,length-1).start(); + + + } 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/group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java b/group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java new file mode 100644 index 0000000000..b1cc492c33 --- /dev/null +++ b/group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java @@ -0,0 +1,115 @@ +package com.coderising.download; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; + +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; + +public class FileDownloaderTest { + boolean downloadFinished = false; + private static Integer pages=1; // 网页数 + + private static boolean exeFlag=true; // 执行标识 + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testDownload() { + + String url="http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.0.41/bin/apache-tomcat-8.0.41-windows-x64.zip"; + 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 (Exception e) { + e.printStackTrace(); + } + } + System.out.println("下载完成!"); + + + + } + + //http://image.so.com/v?ie=utf-8&src=hao_360so&q=%E9%AB%98%E5%9C%86%E5%9C%86&correct=%E9%AB%98%E5%9C%86%E5%9C%86&fromurl=http%3A%2F%2Fwww.cesiu.org.cn%2Fomdsj%2F2010674.html&gsrc=1#multiple=0&dataindex=57&id=537876d111c8adfec7fbda2b80a4f67b + @Test + public void testOpen() throws ConnectionException { + + + + ExecutorService executorService=Executors.newFixedThreadPool(10); // 创建ExecutorService 连接池创建固定的10个初始线程 + + while(exeFlag){ + if(pages<=100){ +// executorService.execute(new Runnable(){ +// +// @Override +// public void run() { +// // TODO Auto-generated method stub +// System.out.println(Thread.currentThread().getName()); +// System.out.println("爬取了第"+pages+"网页..."); +// pages++; +// } +// +// }); + new Runnable(){ + + @Override + public void run() { + // TODO Auto-generated method stub + System.out.println(Thread.currentThread().getName()); + System.out.println("爬取了第"+pages+"网页..."); + pages++; + } + + }.run();; + + }else{ + if(((ThreadPoolExecutor)executorService).getActiveCount()==0){ // 活动线程是0 + executorService.shutdown(); // 结束所有线程 + exeFlag=false; + System.out.println("爬虫任务已经完成"); + } + } + try { + // Thread.sleep(2000); // 线程休息0.1秒 + } catch (Exception e) { + e.printStackTrace(); + } + + } + + } +} diff --git a/group04/844028312/three/src/com/coderising/download/api/Connection.java b/group04/844028312/three/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group04/844028312/three/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/844028312/three/src/com/coderising/download/api/ConnectionException.java b/group04/844028312/three/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..c3ed7396e7 --- /dev/null +++ b/group04/844028312/three/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + +} diff --git a/group04/844028312/three/src/com/coderising/download/api/ConnectionManager.java b/group04/844028312/three/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..ce045393b1 --- /dev/null +++ b/group04/844028312/three/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/844028312/three/src/com/coderising/download/api/DownloadListener.java b/group04/844028312/three/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group04/844028312/three/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/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java b/group04/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..4849434761 --- /dev/null +++ b/group04/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,54 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.Arrays; + +import com.coderising.download.api.Connection; + +public class ConnectionImpl implements Connection{ + HttpURLConnection urlConnection; + + + + public HttpURLConnection getUrlConnection() { + return urlConnection; + } + + public void setUrlConnection(HttpURLConnection urlConnection) { + this.urlConnection = urlConnection; + } + + @Override + public byte[] read(int startPos, int endPos) throws IOException { + byte[] buffer = new byte[endPos-startPos+1]; + int count=0; + urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + InputStream ips=urlConnection.getInputStream(); + //ips.skip(startPos); + while(count parameters) { + + /* + + 0. 读取配置文件struts.xml + + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 + ("name"="test" , "password"="1234") , + 那就应该调用 setName和setPassword方法 + + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" + + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters + + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 + + */ + + + return null; + } + +} diff --git a/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java b/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java new file mode 100644 index 0000000000..b8c81faf3c --- /dev/null +++ b/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java @@ -0,0 +1,43 @@ +package com.coderising.litestruts; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + + + + + +public class StrutsTest { + + @Test + public void testLoginActionSuccess() { + + String actionName = "login"; + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/homepage.jsp", view.getJsp()); + Assert.assertEquals("login successful", view.getParameters().get("message")); + } + + @Test + public void testLoginActionFailed() { + String actionName = "login"; + Map params = new HashMap(); + params.put("name","test"); + params.put("password","123456"); //密码和预设的不一致 + + View view = Struts.runAction(actionName,params); + + Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); + Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); + } +} diff --git a/group04/844028312/three/src/com/coderising/litestruts/View.java b/group04/844028312/three/src/com/coderising/litestruts/View.java new file mode 100644 index 0000000000..07df2a5dab --- /dev/null +++ b/group04/844028312/three/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/group04/844028312/three/src/com/coderising/litestruts/struts.xml b/group04/844028312/three/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..e5d9aebba8 --- /dev/null +++ b/group04/844028312/three/src/com/coderising/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + \ No newline at end of file diff --git a/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/group12/446031103/src/com/coding/basic/Iterator.java b/group04/844028312/three/src/com/coding/basic/Iterator.java similarity index 100% rename from group12/446031103/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/group04/120549547/base/src/com/coding/basic/List.java b/group04/844028312/three/src/com/coding/basic/List.java similarity index 99% rename from group04/120549547/base/src/com/coding/basic/List.java rename to group04/844028312/three/src/com/coding/basic/List.java index d47df585d9..10d13b5832 100644 --- a/group04/120549547/base/src/com/coding/basic/List.java +++ b/group04/844028312/three/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/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/pom.xml b/group04/916758663/learn03/pom.xml new file mode 100644 index 0000000000..82848b035e --- /dev/null +++ b/group04/916758663/learn03/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + + com.example + download + 1.0-SNAPSHOT + jar + + download + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 4.12 + test + + + + org.assertj + assertj-core + 3.6.2 + test + + + 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 + + + + + + + diff --git a/group05/1094051862/mini-jvm/.gitignore b/group05/1094051862/mini-jvm/.gitignore new file mode 100644 index 0000000000..ae3c172604 --- /dev/null +++ b/group05/1094051862/mini-jvm/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/group05/1094051862/mini-jvm/.project b/group05/1094051862/mini-jvm/.project new file mode 100644 index 0000000000..ec3aa61015 --- /dev/null +++ b/group05/1094051862/mini-jvm/.project @@ -0,0 +1,17 @@ + + + mini-jvm + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..86f1100e6c --- /dev/null +++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,88 @@ +package com.coderising.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.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, 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..b15eb7e99d --- /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 - - - - - - - + + + + + + + + diff --git a/group05/1094051862/test01/.gitignore b/group05/1094051862/test01/.gitignore index ae3c172604..3e2fcc7171 100644 --- a/group05/1094051862/test01/.gitignore +++ b/group05/1094051862/test01/.gitignore @@ -1 +1 @@ -/bin/ +/bin/ diff --git a/group05/1094051862/test01/.project b/group05/1094051862/test01/.project index 1dfd9165c6..6be5013dd0 100644 --- a/group05/1094051862/test01/.project +++ b/group05/1094051862/test01/.project @@ -1,17 +1,17 @@ - - - test01 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - + + + test01 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs b/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs index d17b6724d1..980b98c1d5 100644 --- a/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs +++ b/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,12 @@ -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.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 +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.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/group05/1094051862/test01/src/com/coding/basic/ArrayList.java b/group05/1094051862/test01/src/com/coding/basic/ArrayList.java index 60fe8b9150..2e837dd195 100644 --- a/group05/1094051862/test01/src/com/coding/basic/ArrayList.java +++ b/group05/1094051862/test01/src/com/coding/basic/ArrayList.java @@ -1,79 +1,79 @@ -package com.coding.basic; - -import java.util.Arrays; - -public class ArrayList implements List { - - private int size = 0; - - private Object[] elementData = new Object[10]; - - private int increaseSize = 10; - private void increaseArray() { - Object[] newData = Arrays.copyOf(elementData, elementData.length + increaseSize); - elementData = newData; - } - public void add(Object o){ - if (size == elementData.length) { - increaseArray(); - elementData[size++] = o; - } else { - elementData[size++] = o; - } - } - public void add(int index, Object o){ - if (index < 0 || index > size) { - System.out.println("错误提示:index > size || index < 0"); - return; - } - Object temp; - for (int i = index; i < size; i++) { - temp = elementData[i]; - elementData[i] = o; - o = temp; - } - elementData[size ++] = o; - } - - public Object get(int index){ - if (index < 0 || index > size ){ - return null; - } - return elementData[index]; - } - - public Object remove(int index){ - if (index < 0 || index > size ){ - return null; - } - Object result = elementData[index]; - for (int i = index; i < size-1; i++) { - elementData[i] = elementData[i + 1]; - } - elementData[size-1] = null; - size --; - return result; - } - - public int size(){ - return size; - } - - public Iterator iterator(){ - return new Iterator() { - private int cusor = 0; - @Override - public Object next() { - if (!hasNext()) { - System.out.println("next: !hasNext"); - return null; - } - return elementData[cusor ++]; - } - @Override - public boolean hasNext() { - return cusor < size; - } - }; - } -} +package com.coding.basic; + +import java.util.Arrays; + +public class ArrayList implements List { + + private int size = 0; + + private Object[] elementData = new Object[10]; + + private int increaseSize = 10; + private void increaseArray() { + Object[] newData = Arrays.copyOf(elementData, elementData.length + increaseSize); + elementData = newData; + } + public void add(Object o){ + if (size == elementData.length) { + increaseArray(); + elementData[size++] = o; + } else { + elementData[size++] = o; + } + } + public void add(int index, Object o){ + if (index < 0 || index > size) { + System.out.println("错误提示:index > size || index < 0"); + return; + } + Object temp; + for (int i = index; i < size; i++) { + temp = elementData[i]; + elementData[i] = o; + o = temp; + } + elementData[size ++] = o; + } + + public Object get(int index){ + if (index < 0 || index > size ){ + return null; + } + return elementData[index]; + } + + public Object remove(int index){ + if (index < 0 || index > size ){ + return null; + } + Object result = elementData[index]; + for (int i = index; i < size-1; i++) { + elementData[i] = elementData[i + 1]; + } + elementData[size-1] = null; + size --; + return result; + } + + public int size(){ + return size; + } + + public Iterator iterator(){ + return new Iterator() { + private int cusor = 0; + @Override + public Object next() { + if (!hasNext()) { + System.out.println("next: !hasNext"); + return null; + } + return elementData[cusor ++]; + } + @Override + public boolean hasNext() { + return cusor < size; + } + }; + } +} diff --git a/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java b/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java index d7ac820192..266eff3d56 100644 --- a/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java +++ b/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java @@ -1,32 +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; - } - -} +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/group05/1094051862/test01/src/com/coding/basic/Iterator.java b/group05/1094051862/test01/src/com/coding/basic/Iterator.java index 06ef6311b2..dbe8b9afb2 100644 --- a/group05/1094051862/test01/src/com/coding/basic/Iterator.java +++ b/group05/1094051862/test01/src/com/coding/basic/Iterator.java @@ -1,7 +1,7 @@ -package com.coding.basic; - -public interface Iterator { - public boolean hasNext(); - public Object next(); - -} +package com.coding.basic; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group05/1094051862/test01/src/com/coding/basic/Queue.java b/group05/1094051862/test01/src/com/coding/basic/Queue.java index b65d01ab8e..e16a80b13c 100644 --- a/group05/1094051862/test01/src/com/coding/basic/Queue.java +++ b/group05/1094051862/test01/src/com/coding/basic/Queue.java @@ -1,25 +1,25 @@ -package com.coding.basic; - -public class Queue { - private List list = new ArrayList(); - private int size = 0; - public void enQueue(Object o){ - list.add(o); - size ++; - } - - public Object deQueue(){ - if (size == 0) - return null; - size --; - return list.remove(0); - } - - public boolean isEmpty(){ - return size == 0; - } - - public int size(){ - return size; - } -} +package com.coding.basic; + +public class Queue { + private List list = new ArrayList(); + private int size = 0; + public void enQueue(Object o){ + list.add(o); + size ++; + } + + public Object deQueue(){ + if (size == 0) + return null; + size --; + return list.remove(0); + } + + public boolean isEmpty(){ + return size == 0; + } + + public int size(){ + return size; + } +} diff --git a/group05/1094051862/test01/src/com/coding/basic/QueueTest.java b/group05/1094051862/test01/src/com/coding/basic/QueueTest.java index f75beb397f..1feee8dde1 100644 --- a/group05/1094051862/test01/src/com/coding/basic/QueueTest.java +++ b/group05/1094051862/test01/src/com/coding/basic/QueueTest.java @@ -1,26 +1,24 @@ -package com.coding.basic; - -import static org.junit.Assert.*; -import junit.framework.Assert; - -import org.junit.Test; - -import sun.org.mozilla.javascript.internal.ast.NewExpression; - -public class QueueTest { - - @Test - public void test() { - Queue queue = new Queue(); - for (int i = 0; i < 100; i++) { - queue.enQueue(i); - } - Assert.assertEquals(100, queue.size()); - for (int i = 0; i < 100; i++) { - Assert.assertEquals(i, queue.deQueue()); - } - Assert.assertEquals(0, queue.size()); - - } - -} +package com.coding.basic; + +import static org.junit.Assert.*; +import junit.framework.Assert; + +import org.junit.Test; + +public class QueueTest { + + @Test + public void test() { + Queue queue = new Queue(); + for (int i = 0; i < 100; i++) { + queue.enQueue(i); + } + Assert.assertEquals(100, queue.size()); + for (int i = 0; i < 100; i++) { + Assert.assertEquals(i, queue.deQueue()); + } + Assert.assertEquals(0, queue.size()); + + } + +} diff --git a/group05/1094051862/test01/src/com/coding/basic/Stack.java b/group05/1094051862/test01/src/com/coding/basic/Stack.java index 7fabb3494f..57eae3d31d 100644 --- a/group05/1094051862/test01/src/com/coding/basic/Stack.java +++ b/group05/1094051862/test01/src/com/coding/basic/Stack.java @@ -1,28 +1,28 @@ -package com.coding.basic; - -public class Stack { - private List elementData = new ArrayList(); - private int size = 0; - public void push(Object o){ - elementData.add(o); - size ++; - } - - public Object pop(){ - if (size == 0) - return null; - return elementData.remove(--size); - } - - public Object peek(){ - if (size == 0) - return null; - return elementData.get(size - 1); - } - public boolean isEmpty(){ - return size == 0; - } - public int size(){ - return size; - } -} +package com.coding.basic; + +public class Stack { + private List elementData = new ArrayList(); + private int size = 0; + public void push(Object o){ + elementData.add(o); + size ++; + } + + public Object pop(){ + if (size == 0) + return null; + return elementData.remove(--size); + } + + public Object peek(){ + if (size == 0) + return null; + return elementData.get(size - 1); + } + public boolean isEmpty(){ + return size == 0; + } + public int size(){ + return size; + } +} diff --git a/group05/1094051862/test01/src/com/coding/basic/StackTest.java b/group05/1094051862/test01/src/com/coding/basic/StackTest.java index adcb2c6522..e3eabe44a1 100644 --- a/group05/1094051862/test01/src/com/coding/basic/StackTest.java +++ b/group05/1094051862/test01/src/com/coding/basic/StackTest.java @@ -1,26 +1,26 @@ -package com.coding.basic; - -import static org.junit.Assert.*; -import junit.framework.Assert; - -import org.junit.BeforeClass; -import org.junit.Test; - -public class StackTest { - - @Test - public void test() { - Stack stack = new Stack(); - for (int i = 0; i < 100; i++) { - stack.push(i); - } - Assert.assertEquals(100, stack.size()); - Assert.assertEquals(99, stack.pop()); - for (int i = 98; i >= 0; i--) { - Assert.assertEquals(i, stack.peek()); - Assert.assertEquals(i, stack.pop()); - } - Assert.assertEquals(0, stack.size()); - } - -} +package com.coding.basic; + +import static org.junit.Assert.*; +import junit.framework.Assert; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class StackTest { + + @Test + public void test() { + Stack stack = new Stack(); + for (int i = 0; i < 100; i++) { + stack.push(i); + } + Assert.assertEquals(100, stack.size()); + Assert.assertEquals(99, stack.pop()); + for (int i = 98; i >= 0; i--) { + Assert.assertEquals(i, stack.peek()); + Assert.assertEquals(i, stack.pop()); + } + Assert.assertEquals(0, stack.size()); + } + +} diff --git a/group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java new file mode 100644 index 0000000000..3788724596 --- /dev/null +++ b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java @@ -0,0 +1,129 @@ +package com.coding.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;// 链表尾 + + + public LRUPageFrame(int capacity) { + + this.capacity = capacity; + + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + + if (first == null) { + accessFirst(pageNum); + return; + } + if (capacity > 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..5f56d9483f --- /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/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..59d12540fc --- /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..61faafb77d --- /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..0b8eafc282 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java +++ b/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java @@ -1,64 +1,66 @@ -package com.coding.basic; - -public class BinaryTree { - - //根节点 - private BinaryTreeNode root; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public > BinaryTreeNode insert(T o){ - - BinaryTreeNode treeNode = new BinaryTreeNode(); - treeNode.setData(o); - if(root == null){ - root = treeNode; - }else{ - BinaryTreeNode currentNode = root; - BinaryTreeNode parent; - while(true){ - parent = currentNode; - if(((Comparable)currentNode.getData()).compareTo(o)>0){//向左放 - currentNode = currentNode.getLeft(); - if(currentNode == null){ - parent.setLeft(treeNode); - treeNode.setParent(parent); - break; - } - }else{//向右放 - currentNode = currentNode.getRight(); - if(currentNode == null){ - parent.setRight(treeNode); - treeNode.setParent(parent); - break; - } - } - } - } - return treeNode; - } - - /** - * 先序遍历 - * @param node - * @return - */ - public List traversalBefore(BinaryTreeNode node){ - //所有数据集合 - List datas = new ArrayList(); - return traversal(node,datas); - } - private List traversal(BinaryTreeNode node,List datas){ - - if(node !=null){ - datas.add(node.getData()); - traversal(node.getLeft(),datas); - traversal(node.getRight(),datas); - } - return datas; - } - - public BinaryTreeNode getRoot() { - return root; - } - -} +package com.coding.basic; + +import com.coding.basic.array.ArrayList; + +public class BinaryTree { + + //根节点 + private BinaryTreeNode root; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public > BinaryTreeNode insert(T o){ + + BinaryTreeNode treeNode = new BinaryTreeNode(); + treeNode.setData(o); + if(root == null){ + root = treeNode; + }else{ + BinaryTreeNode currentNode = root; + BinaryTreeNode parent; + while(true){ + parent = currentNode; + if(((Comparable)currentNode.getData()).compareTo(o)>0){//向左放 + currentNode = currentNode.getLeft(); + if(currentNode == null){ + parent.setLeft(treeNode); + treeNode.setParent(parent); + break; + } + }else{//向右放 + currentNode = currentNode.getRight(); + if(currentNode == null){ + parent.setRight(treeNode); + treeNode.setParent(parent); + break; + } + } + } + } + return treeNode; + } + + /** + * 先序遍历 + * @param node + * @return + */ + public List traversalBefore(BinaryTreeNode node){ + //所有数据集合 + List datas = new ArrayList(); + return traversal(node,datas); + } + private List traversal(BinaryTreeNode node,List datas){ + + if(node !=null){ + datas.add(node.getData()); + traversal(node.getLeft(),datas); + traversal(node.getRight(),datas); + } + return datas; + } + + public BinaryTreeNode getRoot() { + return root; + } + +} 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..aa8429ac59 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java +++ b/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java @@ -1,26 +1,28 @@ -package com.coding.basic; - -public class Queue { - - private LinkedList element = new LinkedList(); - - public void enQueue(Object o){ - - element.add(o); - } - - public Object deQueue(){ - - return element.removeFirst(); - } - - public boolean isEmpty(){ - - return element.size()==0; - } - - public int size(){ - - return element.size(); - } -} +package com.coding.basic; + +import com.coding.basic.linklist.LinkedList; + +public class Queue { + + private LinkedList element = new LinkedList(); + + public void enQueue(Object o){ + + element.add(o); + } + + public Object deQueue(){ + + return element.removeFirst(); + } + + public boolean isEmpty(){ + + return element.size()==0; + } + + public int size(){ + + return element.size(); + } +} 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..2b08e856c1 100644 --- a/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java +++ b/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java @@ -1,28 +1,30 @@ -package com.coding.basic; - -public class Stack { - - private ArrayList elementData = new ArrayList(); - - public void push(Object o){ - - elementData.add(o); - } - - public Object pop(){ - - return elementData.remove(size()-1); - } - - public Object peek(){ - - return elementData.get(size()-1); - } - public boolean isEmpty(){ - - return size()==0; - } - public int size(){ - return elementData.size(); - } -} +package com.coding.basic; + +import com.coding.basic.array.ArrayList; + +public class Stack { + + private ArrayList elementData = new ArrayList(); + + public void push(Object o){ + + elementData.add(o); + } + + public Object pop(){ + + return elementData.remove(size()-1); + } + + public Object peek(){ + + return elementData.get(size()-1); + } + public boolean isEmpty(){ + + return size()==0; + } + public int size(){ + return elementData.size(); + } +} 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 91% 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..4bbf60adf9 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,7 +1,10 @@ -package com.coding.basic; +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; 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..de11fdbca5 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,6 +1,5 @@ -package com.coderising.array; +package com.coding.basic.array; -import com.coding.basic.ArrayList; public class ArrayUtil { 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..4d1c587fd3 --- /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(sizeparameters){ 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..9ba4ff935b --- /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..fb2f3be0a6 --- /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..d36b122f60 --- /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..a3ce652047 --- /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/group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java b/group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java new file mode 100644 index 0000000000..06ef6311b2 --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coding/basic/LinkedList.java b/group12/563253496/week3_file_download/src/com/coding/basic/LinkedList.java new file mode 100644 index 0000000000..4fdb03db8a --- /dev/null +++ b/group12/563253496/week3_file_download/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/group12/563253496/week3_file_download/src/com/coding/basic/List.java b/group12/563253496/week3_file_download/src/com/coding/basic/List.java new file mode 100644 index 0000000000..10d13b5832 --- /dev/null +++ b/group12/563253496/week3_file_download/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/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/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..4127673b7e --- /dev/null +++ b/group12/563253496/week4_jvm1/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 = "D:\\mygit\\coding2017\\group12\\563253496\\week4_jvm1\\out\\production\\week4_jvm1"; + 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 +* @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/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 3c3462637e..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 @@ -185,16 +185,21 @@ public void removeFirstSize(int firstSize) { * @param length */ public void remove(int i, int length) { - if (i == 0 ) {removeFirstSize(length); return;} - if (i >= size || length == 0) {return;} + 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); + length = length <= lastLenth ? length : lastLenth; + Node pre = node(i - 1); int j = 0; Node next = pre; - while (j++ < length){ + while (j++ < length) { next = next.next; } pre.next = next.next; @@ -213,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中出现的元素 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 baca03b06b..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 @@ -3,6 +3,8 @@ import org.junit.Assert; import org.junit.Test; +import java.util.Arrays; + /** * Created by luoziyihao on 3/23/17. */ @@ -83,9 +85,12 @@ private LinkedList createAndFillLinkedList() { } private LinkedList createAndFillLinkedList(int length) { + return createAndFillLinkedList(1, length); + } + private LinkedList createAndFillLinkedList(int start, int length) { LinkedList linkedList = new LinkedList(); - for (int i = 1; i <= length; i++) { + for (int i = start; i <= length; i++) { linkedList.add(i); } return linkedList; @@ -136,6 +141,9 @@ public void remove7() throws Exception { @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))); } 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/assignment2_26/LoginAction.java b/group17/1264835468/src/assignment0226/LoginAction.java similarity index 91% rename from group17/1264835468/src/assignment2_26/LoginAction.java rename to group17/1264835468/src/assignment0226/LoginAction.java index 3101d322b8..652b5359ac 100644 --- a/group17/1264835468/src/assignment2_26/LoginAction.java +++ b/group17/1264835468/src/assignment0226/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 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/assignment2_26/StrutsTest.java b/group17/1264835468/src/assignment0226/StrutsTest.java similarity index 94% rename from group17/1264835468/src/assignment2_26/StrutsTest.java rename to group17/1264835468/src/assignment0226/StrutsTest.java index f47410209b..1e677c38b3 100644 --- a/group17/1264835468/src/assignment2_26/StrutsTest.java +++ b/group17/1264835468/src/assignment0226/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 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/assignment2_26/View.java b/group17/1264835468/src/assignment0226/View.java similarity index 87% rename from group17/1264835468/src/assignment2_26/View.java rename to group17/1264835468/src/assignment0226/View.java index e96197fad6..3bd518e451 100644 --- a/group17/1264835468/src/assignment2_26/View.java +++ b/group17/1264835468/src/assignment0226/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 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/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java b/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java new file mode 100644 index 0000000000..067cd93c2b --- /dev/null +++ b/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java @@ -0,0 +1,86 @@ +package jvm_1; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by william on 2017/4/5. + */ +public class ClassFileloaderTest { + static String path1 = "D:\\workspace\\IDEA\\homework\\coding2017\\group17\\785396327\\out\\production\\785396327"; + 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 = "jvm_1.EmployeeV1"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1020, byteCodes.length); + + } + + + @Test + public void testMagicNumber(){ + ClassFileLoader loader = new ClassFileLoader(); + 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]}; + + + 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) { + 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..70ec469ee6 --- /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..45638bd851 --- /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..e2ed056cc3 --- /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..e05d4b750e --- /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/group23/565832157/src/com/coding/basic/LinkedList.java b/group23/565832157/src/com/coding/basic/LinkedList.java index 09fe0a8ff3..7d037a6428 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/group26/1515345281/.classpath b/group26/1515345281/.classpath new file mode 100644 index 0000000000..0b147a3172 --- /dev/null +++ b/group26/1515345281/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/group26/1515345281/.gitignore b/group26/1515345281/.gitignore index 4f4c622218..50fe13f0ff 100644 --- a/group26/1515345281/.gitignore +++ b/group26/1515345281/.gitignore @@ -1,2 +1,4 @@ -/bin -/.project/.classpath \ No newline at end of file +/bin +/.project/.classpath +/.settings +/lib \ No newline at end of file diff --git a/group26/1515345281/.project b/group26/1515345281/.project new file mode 100644 index 0000000000..a58f6ad71c --- /dev/null +++ b/group26/1515345281/.project @@ -0,0 +1,17 @@ + + + 1515345281Learning + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group26/1515345281/src/Collection/blog b/group26/1515345281/src/Collection/blog new file mode 100644 index 0000000000..87966e2eba --- /dev/null +++ b/group26/1515345281/src/Collection/blog @@ -0,0 +1 @@ +浅谈CPU,内存,硬盘,指令之间的关系http://blog.csdn.net/sjshenjian/article/details/68946823 \ No newline at end of file diff --git a/group26/1515345281/src/week1/collection/test/ArrayListTest.java b/group26/1515345281/src/week1/collection/test/ArrayListTest.java index 0fa7701041..552420ba65 100644 --- a/group26/1515345281/src/week1/collection/test/ArrayListTest.java +++ b/group26/1515345281/src/week1/collection/test/ArrayListTest.java @@ -1,69 +1,69 @@ -package week1.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import week1.collection.ArrayList; -import week1.collection.Iterator; - -public class ArrayListTest { - - private ArrayList list=new ArrayList(); - - @Test - public void testAddObject(){ - list.add(1); - assertEquals(1 , list.get(0)); - } - - @Test - public void testAddIndexObject(){ - list.add("aa"); - list.add("bb"); - list.add(0,"cc"); - assertEquals("cc",list.get(0)); - try{ - list.add(-1,"pp"); - fail("- can't be index"); - - list.add(list.size()+100,"bb"); - fail("index should <= size"); - - }catch(Exception ex){ - - } - } - - @Test - public void testGetObject(){ - list.add(1); - assertEquals(1,list.get(0)); - } - - @Test - public void testRemoveObject(){ - list.add(1); - list.add(2); - list.add(3); - list.remove(0); - list.remove(2); - assertEquals(2,list.get(0)); - } - - @Test - public void testSize(){ - assertEquals(0,list.size()); - } - - @Test - public void testIterator(){ - list.add(1); - list.add(2); - list.add(3); - Iterator it=list.iterator(); - while(it.hasNext()){ - System.out.println(it.next()); - } - } -} +package week1.collection.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import week1.collection.ArrayList; +import week1.collection.Iterator; + +public class ArrayListTest { + + private ArrayList list=new ArrayList(); + + @Test + public void testAddObject(){ + list.add(1); + assertEquals(1 , list.get(0)); + } + + @Test + public void testAddIndexObject(){ + list.add("aa"); + list.add("bb"); + list.add(0,"cc"); + assertEquals("cc",list.get(0)); + try{ + list.add(-1,"pp"); + fail("- can't be index"); + + list.add(list.size()+100,"bb"); + fail("index should <= size"); + + }catch(Exception ex){ + + } + } + + @Test + public void testGetObject(){ + list.add(1); + assertEquals(1,list.get(0)); + } + + @Test + public void testRemoveObject(){ + list.add(1); + list.add(2); + list.add(3); + list.remove(0); + list.remove(2); + assertEquals(2,list.get(0)); + } + + @Test + public void testSize(){ + assertEquals(0,list.size()); + } + + @Test + public void testIterator(){ + list.add(1); + list.add(2); + list.add(3); + Iterator it=list.iterator(); + while(it.hasNext()){ + System.out.println(it.next()); + } + } +} diff --git a/group26/1515345281/src/week1/collection/test/BinarySearchTreeTest.java b/group26/1515345281/src/week1/collection/test/BinarySearchTreeTest.java index a6ea1cac3f..b612bfb0ee 100644 --- a/group26/1515345281/src/week1/collection/test/BinarySearchTreeTest.java +++ b/group26/1515345281/src/week1/collection/test/BinarySearchTreeTest.java @@ -1,23 +1,23 @@ -package week1.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import week1.collection.BinaryTreeNode; - -public class BinarySearchTreeTest { - - private BinaryTreeNode root=new BinaryTreeNode(5); - - @Test - public void testInsert(){ - root.insert(2); - root.insert(2); - root.insert(7); - root.insert(1); - root.insert(4); - root.insert(3); - assertEquals(3,root.getLeft().getRight().getLeft().getData()); - } -} +package week1.collection.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import week1.collection.BinaryTreeNode; + +public class BinarySearchTreeTest { + + private BinaryTreeNode root=new BinaryTreeNode(5); + + @Test + public void testInsert(){ + root.insert(2); + root.insert(2); + root.insert(7); + root.insert(1); + root.insert(4); + root.insert(3); + assertEquals(3,root.getLeft().getRight().getLeft().getData()); + } +} diff --git a/group26/1515345281/src/week1/collection/test/LinkedListTest.java b/group26/1515345281/src/week1/collection/test/LinkedListTest.java index cba45c719d..94475a22bb 100644 --- a/group26/1515345281/src/week1/collection/test/LinkedListTest.java +++ b/group26/1515345281/src/week1/collection/test/LinkedListTest.java @@ -1,90 +1,90 @@ -package week1.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import week1.collection.Iterator; -import week1.collection.LinkedList; - -public class LinkedListTest { - - private LinkedList list=new LinkedList(); - - @Test - public void testAdd(){ - list.add("1"); - list.add("2"); - list.add("3"); - assertEquals("1",list.get(0)); - assertEquals("2",list.get(1)); - assertEquals(3,list.size()); - } - - @Test - public void testAddByIndex(){ - list.add(2); - list.add(4); - list.add(6); - list.add(0,0); - list.add(3,3); - list.add(5,7); - assertEquals(0, list.get(0)); - assertEquals(3, list.get(3)); - assertEquals(7, list.get(5)); - try{ - list.add(-1,0); - fail("-1 not a correctly index"); - }catch(Exception ex){ - - } - } - - @Test - public void testGet(){ - list.add(0); - list.add(1); - list.add(2); - assertEquals(0,list.get(0)); - } - - @Test - public void testRemove(){ - list.add(0); - list.add(1); - list.add(2); - list.add(3); - list.add(4); - assertEquals(0,list.remove(0)); - assertEquals(4,list.remove(3)); - assertEquals(2,list.remove(1)); - } - - @Test - public void testSize(){ - list.add(0); - list.addLast(0); - list.addFirst(0); - list.remove(0); - list.removeLast(); - list.removeFirst(); - assertEquals(0,list.size()); - } - - @Test - public void testOther(){ - list.add(1); - list.add(1); - list.add(1); - list.add(1); - list.addFirst(0); - list.addLast(2); - list.removeFirst(); - list.removeLast(); - Iterator it=list.iterator(); - while(it.hasNext()){ - System.out.print(it.next()+" "); - } - } - -} +package week1.collection.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import week1.collection.Iterator; +import week1.collection.LinkedList; + +public class LinkedListTest { + + private LinkedList list=new LinkedList(); + + @Test + public void testAdd(){ + list.add("1"); + list.add("2"); + list.add("3"); + assertEquals("1",list.get(0)); + assertEquals("2",list.get(1)); + assertEquals(3,list.size()); + } + + @Test + public void testAddByIndex(){ + list.add(2); + list.add(4); + list.add(6); + list.add(0,0); + list.add(3,3); + list.add(5,7); + assertEquals(0, list.get(0)); + assertEquals(3, list.get(3)); + assertEquals(7, list.get(5)); + try{ + list.add(-1,0); + fail("-1 not a correctly index"); + }catch(Exception ex){ + + } + } + + @Test + public void testGet(){ + list.add(0); + list.add(1); + list.add(2); + assertEquals(0,list.get(0)); + } + + @Test + public void testRemove(){ + list.add(0); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + assertEquals(0,list.remove(0)); + assertEquals(4,list.remove(3)); + assertEquals(2,list.remove(1)); + } + + @Test + public void testSize(){ + list.add(0); + list.addLast(0); + list.addFirst(0); + list.remove(0); + list.removeLast(); + list.removeFirst(); + assertEquals(0,list.size()); + } + + @Test + public void testOther(){ + list.add(1); + list.add(1); + list.add(1); + list.add(1); + list.addFirst(0); + list.addLast(2); + list.removeFirst(); + list.removeLast(); + Iterator it=list.iterator(); + while(it.hasNext()){ + System.out.print(it.next()+" "); + } + } + +} diff --git a/group26/1515345281/src/week1/collection/test/QueueTest.java b/group26/1515345281/src/week1/collection/test/QueueTest.java index 81979682a6..96d61403eb 100644 --- a/group26/1515345281/src/week1/collection/test/QueueTest.java +++ b/group26/1515345281/src/week1/collection/test/QueueTest.java @@ -1,27 +1,27 @@ -package week1.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import week1.collection.Queue; - -public class QueueTest { - - private Queue queue=new Queue(); - - @Test - public void testEnQueue(){ - queue.enQueue("123"); - queue.enQueue("456"); - assertEquals("123",queue.deQueue()); - } - - @Test - public void testDeQueue(){ - queue.enQueue("123"); - queue.enQueue("456"); - queue.deQueue(); - assertEquals("456",queue.deQueue()); - } -} +package week1.collection.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import week1.collection.Queue; + +public class QueueTest { + + private Queue queue=new Queue(); + + @Test + public void testEnQueue(){ + queue.enQueue("123"); + queue.enQueue("456"); + assertEquals("123",queue.deQueue()); + } + + @Test + public void testDeQueue(){ + queue.enQueue("123"); + queue.enQueue("456"); + queue.deQueue(); + assertEquals("456",queue.deQueue()); + } +} diff --git a/group26/1515345281/src/week1/collection/test/StackTest.java b/group26/1515345281/src/week1/collection/test/StackTest.java index 717bf9b6a8..6d0f49947e 100644 --- a/group26/1515345281/src/week1/collection/test/StackTest.java +++ b/group26/1515345281/src/week1/collection/test/StackTest.java @@ -1,56 +1,56 @@ -package week1.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import week1.collection.Stack; - -public class StackTest { - - private Stack stack=new Stack(); - - @Test - public void testPush(){ - stack.push("hello"); - stack.push("world"); - assertEquals("world",stack.peek()); - } - - @Test - public void testPop(){ - stack.push("hello"); - stack.push("world"); - assertEquals("world",stack.pop()); - assertEquals(1,stack.size()); - } - - @Test - public void testPeek(){ - stack.push("world"); - assertEquals("world",stack.peek()); - stack.pop(); - try{ - stack.peek(); - fail("stack is empty,can't do peek"); - - }catch(Exception ex){ - - } - } - - @Test - public void testEmpty(){ - assertEquals(true,stack.isEmpty()); - stack.push("hello"); - stack.push("world"); - assertEquals(false,stack.isEmpty()); - } - - @Test - public void testSize(){ - stack.push("hello"); - stack.pop(); - assertEquals(0,stack.size()); - } -} +package week1.collection.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import week1.collection.Stack; + +public class StackTest { + + private Stack stack=new Stack(); + + @Test + public void testPush(){ + stack.push("hello"); + stack.push("world"); + assertEquals("world",stack.peek()); + } + + @Test + public void testPop(){ + stack.push("hello"); + stack.push("world"); + assertEquals("world",stack.pop()); + assertEquals(1,stack.size()); + } + + @Test + public void testPeek(){ + stack.push("world"); + assertEquals("world",stack.peek()); + stack.pop(); + try{ + stack.peek(); + fail("stack is empty,can't do peek"); + + }catch(Exception ex){ + + } + } + + @Test + public void testEmpty(){ + assertEquals(true,stack.isEmpty()); + stack.push("hello"); + stack.push("world"); + assertEquals(false,stack.isEmpty()); + } + + @Test + public void testSize(){ + stack.push("hello"); + stack.pop(); + assertEquals(0,stack.size()); + } +} diff --git a/group26/1515345281/src/week2/arrayutil/ArrayUtil.java b/group26/1515345281/src/week2/arrayutil/ArrayUtil.java index dcc530949d..f2a8e33e6e 100644 --- a/group26/1515345281/src/week2/arrayutil/ArrayUtil.java +++ b/group26/1515345281/src/week2/arrayutil/ArrayUtil.java @@ -1,225 +1,233 @@ -package week2.arrayutil; - -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;i list=new ArrayList(); - int i=0; - int j=0; - while(i array2[j]){ - list.add(array2[j]); - j++; - }else{ - list.add(array1[i]); - i++; - j++; - } - } - while(i=result.length ){ - result=this.grow(result, 5); - } - result[cursor]=result[cursor-2]+result[cursor-1]; - cursor++; - } - return result; - } - - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public int[] getPrimes(int max){ - if(max<=1){ - return new int[0]; - } - if(max == 2){ - return new int[]{2}; - } - - int[] temp=new int[max]; - temp[2]=2; - int primeNum=0; - for(int i=3;i list=new ArrayList(); - for(int i=6;i list=new ArrayList(); + int i=0; + int j=0; + while(i array2[j]){ + list.add(array2[j]); + j++; + }else{ + list.add(array1[i]); + i++; + j++; + } + } + while(i=result.length ){ + result=this.grow(result, 5); + } + result[cursor]=result[cursor-2]+result[cursor-1]; + cursor++; + } + return result; + } + + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + if(max<=1){ + return new int[0]; + } + if(max == 2){ + return new int[]{2}; + } + + int[] temp=new int[max]; + temp[2]=2; + int primeNum=0; + for(int i=3;i list=new ArrayList(); + for(int i=6;i 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..6cab04468f 100644 --- a/group26/1515345281/src/week2/struts2/View.java +++ b/group26/1515345281/src/week2/struts2/View.java @@ -1,23 +1,24 @@ -package week2.struts2; - -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 week2.struts2; + +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/1515345281/src/week2/struts2/struts.xml b/group26/1515345281/src/week2/struts2/struts.xml index 9e69fa4e47..139267b2f8 100644 --- a/group26/1515345281/src/week2/struts2/struts.xml +++ b/group26/1515345281/src/week2/struts2/struts.xml @@ -1,12 +1,13 @@ - - - - /jsp/homepage.jsp - /jsp/showLogin.jsp - - - - /jsp/welcome.jsp - /jsp/error.jsp - + + + + /jsp/homepage.jsp + /jsp/showLogin.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..223fec106d --- /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..14dd9a5d9c --- /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..766eafe426 --- /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..641cea3284 --- /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..6fc0a88f24 --- /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..eec402fbe1 --- /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..45cdff4b8e --- /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..a4c14a90dd --- /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..9a0daa3f86 --- /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..6eae1f7256 --- /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..f7aea53397 --- /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..f66705b1c5 --- /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..2e9d0af24b --- /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/week2/struts/struts.xml b/group26/2441547139/week2/struts/struts.xml new file mode 100644 index 0000000000..5b508e48c8 --- /dev/null +++ b/group26/2441547139/week2/struts/struts.xml @@ -0,0 +1,8 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + \ No newline at end of file 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..4903af944f --- /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..de60ce339d --- /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..b633c0c767 --- /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..07953fc013 --- /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..a7494563ef --- /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/struts.xml b/group26/723161901/src/com/litestruts/struts.xml new file mode 100644 index 0000000000..84c494845f --- /dev/null +++ b/group26/723161901/src/com/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + \ No newline at end of file diff --git a/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..53d700fb78 --- /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..6398a1db19 --- /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..faa1ca0b8c --- /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..c4b62c8ddf --- /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..9e5bec4564 --- /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..be45f69dde --- /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..fa07be7cf4 --- /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..569afb0cb3 --- /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 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/383117348/src/com/coderising/jvm/loader/ClassFileLoader.java b/group27/383117348/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..09051be9b6 --- /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..33229dccb2 --- /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..d36b122f60 --- /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..20b393843e --- /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;i7->10 , 逆置后变为 10->7->3 + * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ - public void reverse(){ - Node head = first; - Node reverse = null; - while (head != null) { - Node second = head.next; - head.next = reverse; - reverse = head; - head = second; - } - first = reverse; - } - //有问题 + public void reverse() { + if (size == 0) + return; + + for (int i = 1; i < size; i++) { + addFirst(get(i)); + remove(i + 1); + } + + } + @Test - public void testReverse(){ + public void testReverse() { LinkedList list = getList(); Iterator ite = list.iterator(); - while(ite.hasNext()){ - System.out.print(ite.next()+" "); + while (ite.hasNext()) { + System.out.print(ite.next() + " "); } list.reverse(); Iterator it = list.iterator(); - while(it.hasNext()){ - System.out.println("----"); - System.out.print(it.next()+" "); + 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 + * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 + * ,删除以后的值为7,8,10 */ - public void removeFirstHalf(){ - int mid = (int) Math.ceil(size/2.0); - for(int x=0;x0){ - - Node prev = getNodeByIndex(i-1); - Node next = getNodeByIndex(i+length); - for(int x=i;x 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] + * 假定当前链表和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)); - } - - System.out.println(Arrays.toString(array)); + 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; + return array; } - + /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 从当前链表中中删除在list中出现的元素 + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 + * * @param list */ - - public void subtract(LinkedList 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; - } - } - } - } - + 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(){ + public void removeDuplicateValues() { for (int i = size - 1; i > 0; i--) { - if (get(i) == get(i - 1)) { - remove(i); - } - } + if (get(i) == get(i - 1)) { + remove(i); + } + } } - + /** - * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 - * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) + * * @param min * @param max */ - public void removeRange(int min, int 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); - } - } + int element = ((int) get(i)); + if ((element > min) && element < max) { + remove(i); + } + } } - + /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * * @param list */ - public LinkedList intersection( LinkedList list){ + public LinkedList intersection(LinkedList list) { LinkedList newList = new LinkedList(); - int length = list.size(); - for (int i = 0; i < size; i++) { - for (int j = 0; j < length; j++) { - if (get(i) == list.get(j)) { - newList.add(get(i)); - break; - } - } - } - - Iterator it = newList.iterator(); - while (it.hasNext()) { - System.out.print(it.next() + " "); - } - System.out.println(); - return newList; + 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; } /*------------------------------------------------------单元测试----------------------------------------------------*/ @@ -542,8 +510,8 @@ public void TestIterator() { System.out.println(ite.next()); } } - - private LinkedList getList(){ + + private LinkedList getList() { LinkedList list = new LinkedList(); for (int i = 0; i < 10; i++) { list.add(i); diff --git a/group27/513274874/.gitignore b/group27/513274874/.gitignore new file mode 100644 index 0000000000..3f330393a1 --- /dev/null +++ b/group27/513274874/.gitignore @@ -0,0 +1 @@ +/homework/ diff --git a/group27/513274874/data-structure/.classpath b/group27/513274874/data-structure/.classpath new file mode 100644 index 0000000000..2d7497573f --- /dev/null +++ b/group27/513274874/data-structure/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/group27/513274874/data-structure/.gitignore b/group27/513274874/data-structure/.gitignore new file mode 100644 index 0000000000..ae3c172604 --- /dev/null +++ b/group27/513274874/data-structure/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/group27/513274874/data-structure/.project b/group27/513274874/data-structure/.project new file mode 100644 index 0000000000..b6d8ce6204 --- /dev/null +++ b/group27/513274874/data-structure/.project @@ -0,0 +1,17 @@ + + + coding2017 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/group27/513274874/data-structure/down.jpg b/group27/513274874/data-structure/down.jpg new file mode 100644 index 0000000000..d7fccb49d2 Binary files /dev/null and b/group27/513274874/data-structure/down.jpg differ 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..ff496b8d4d --- /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..31cb31f730 --- /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/group12/446031103/src/com/coderising/download/FileDownloaderTest.java b/group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java similarity index 95% rename from group12/446031103/src/com/coderising/download/FileDownloaderTest.java rename to group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java index 4ff7f46ae0..d8874d5981 100644 --- a/group12/446031103/src/com/coderising/download/FileDownloaderTest.java +++ b/group27/513274874/data-structure/src/com/coderising/download/FileDownloaderTest.java @@ -1,59 +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("下载完成!"); - - - - } - -} +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..9710e270e1 --- /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..8dbfe95dda --- /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..fb44ede457 --- /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..4cd0b3eab1 --- /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..ea9ad0f25e --- /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..2f04b22b9d --- /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 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(); + + Iterator actions = root.elementIterator(); + while (actions.hasNext()) { + Element action = actions.next(); + List 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 results = action.elementIterator(); + while (results.hasNext()) { + Element result = results.next(); + List 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 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 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 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中的 配置,以及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 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 result = new HashMap<>(); + + public StrutsXml(String actionName, String clazz, Map 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 getResult() { + return result; + } + + public void setResult(Map 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 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/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/coderising/litestruts/struts.xml b/group27/513274874/data-structure/src/com/coderising/litestruts/struts.xml new file mode 100644 index 0000000000..0582b7d4ea --- /dev/null +++ b/group27/513274874/data-structure/src/com/coderising/litestruts/struts.xml @@ -0,0 +1,11 @@ + + + + /jsp/homepage.jsp + /jsp/showLogin.jsp + + + /jsp/welcome.jsp + /jsp/error.jsp + + diff --git a/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 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 + * @version 1.0 + * @since
三月 14, 2017
+ */ +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 100755 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 100755 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 ;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/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 +* @since
三月 6, 2017
+* @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 @@ - coding2017 + ThirdHomework 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 eca4a105e6..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,11 +1,15 @@ package com.coding.coderising.download; + import com.coding.coderising.download.api.Connection; import java.io.IOException; import java.io.RandomAccessFile; + public class DownloadThread extends Thread{ + + Connection conn; int startPos; @@ -17,14 +21,18 @@ public class DownloadThread extends Thread{ public DownloadThread( Connection conn, int startPos, int endPos){ this.conn = conn; + this.startPos = startPos; this.endPos = endPos; + this.filePath = filePath; } + 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 dc99e91598..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,11 +1,13 @@ 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; + public class FileDownloader { String url; @@ -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 list = new ArrayList(); + + 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 8a9531530f..60aa517b5b 100644 --- a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java +++ b/group27/513274874/homework/src/com/coding/coderising/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 = "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/impl/ConnectionImpl.java b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java index e1f649b88b..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,7 +1,9 @@ package com.coding.coderising.download.impl; + import com.coding.coderising.download.api.Connection; + import java.io.*; import java.net.URL; import java.net.URLConnection; @@ -9,6 +11,7 @@ public class ConnectionImpl implements Connection { private URL url; + // 定义字节数组(取水的竹筒)的长度 private final int BUFF_LEN = 32; @@ -16,6 +19,7 @@ public class ConnectionImpl implements Connection { private InputStream is; + ByteArrayOutputStream bos; @Override 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 2295167f6d..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,5 +1,6 @@ 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; @@ -7,11 +8,13 @@ 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; @@ -24,6 +27,7 @@ public Connection open(String url) throws ConnectionException { 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 100755 index 0000000000..4b5d12b49f --- /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 clzPaths = new ArrayList(); + 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 100755 index 0000000000..e5d2bd89c5 --- /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=UTF-8 diff --git a/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java index 434d991447..7fb450d0a0 100644 --- a/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java +++ b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java @@ -1,23 +1,94 @@ package com.coding.basic.stack; - +import java.util.Stack; public class StackUtil { + public static void bad_reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + Stack tmpStack = new Stack(); + while(!s.isEmpty()){ + tmpStack.push(s.pop()); + } + + s = tmpStack; + + } + + + public static void reverse_247565311(Stack s){ + if(s == null || s.isEmpty()) { + return; + } + + int size = s.size(); + Stack tmpStack = new Stack(); + + for(int i=0;ii){ + tmpStack.push(s.pop()); + } + s.push(top); + while(tmpStack.size()>0){ + s.push(tmpStack.pop()); + } + } + } + + /** * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 */ - public static void reverse(Stack s) { - + public static void reverse(Stack s) { + if(s == null || s.isEmpty()){ + return; + } + + Stack tmp = new Stack(); + while(!s.isEmpty()){ + tmp.push(s.pop()); + } + while(!tmp.isEmpty()){ + Integer top = tmp.pop(); + addToBottom(s,top); + } + + + } + public static void addToBottom(Stack 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()); + } } /** @@ -27,7 +98,24 @@ public static void remove(Stack s,Object o) { * @return */ public static Object[] getTop(Stack s,int len) { - return null; + + if(s == null || s.isEmpty() || s.size() stack = new Stack(); + for(int i=0;i 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 testReverse_247565311() { + Stack s = new Stack(); + s.push(1); + s.push(2); + s.push(3); + + Assert.assertEquals("[1, 2, 3]", s.toString()); + StackUtil.reverse_247565311(s); + Assert.assertEquals("[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]); + } + } + + @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..0a145ff047 --- /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..92d130cddd --- /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..89fb53394e --- /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..b0c67b4b93 --- /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..22941f83b1 --- /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 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){ + + 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..3eb2654e36 --- /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..fa69dc9bdb --- /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 items = new ArrayList(); + + 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..44c5d90d46 --- /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/ClassFile.java b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java index 650ca8375d..c21a0988e5 100644 --- a/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java +++ b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java @@ -1,75 +1,92 @@ -package com.coderising.jvm.clz; - -import com.coderising.jvm.constant.ClassInfo; -import com.coderising.jvm.constant.ConstantPool; - -public class ClassFile { - - private int minorVersion; - private int majorVersion; - - private AccessFlag accessFlag; - private ClassIndex clzIndex; - private ConstantPool pool; - - - public ClassIndex getClzIndex() { - return clzIndex; - } - public AccessFlag getAccessFlag() { - return accessFlag; - } - public void setAccessFlag(AccessFlag accessFlag) { - this.accessFlag = accessFlag; - } - - - - public ConstantPool getConstantPool() { - return pool; - } - public int getMinorVersion() { - return minorVersion; - } - public void setMinorVersion(int minorVersion) { - this.minorVersion = minorVersion; - } - public int getMajorVersion() { - return majorVersion; - } - public void setMajorVersion(int majorVersion) { - this.majorVersion = majorVersion; - } - public void setConstPool(ConstantPool pool) { - this.pool = pool; - - } - public void setClassIndex(ClassIndex clzIndex) { - this.clzIndex = clzIndex; - } - - - - - public void print(){ - - if(this.accessFlag.isPublicClass()){ - System.out.println("Access flag : public "); - } - System.out.println("Class Name:"+ getClassName()); - - System.out.println("Super Class Name:"+ getSuperClassName()); - - - } - - private String getClassName(){ - int thisClassIndex = this.clzIndex.getThisClassIndex(); - ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex); - return thisClass.getClassName(); - } - private String getSuperClassName(){ - ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex()); - return superClass.getClassName(); - } -} +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 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/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..09bae5a1ae --- /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 index 9c9fac2839..5c5173fbe8 100644 --- a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java +++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java @@ -1,5 +1,57 @@ -package com.coderising.jvm.loader; - -public class ByteCodeIterator { - -} +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/ClassFileParser.java b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java index 8e29f14a0c..444ec4c60d 100644 --- a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java +++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java @@ -1,44 +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; - -public class ClassFileParser { - - public ClassFile parse(byte[] codes) { - - - - - return null; - } - - private AccessFlag parseAccessFlag(ByteCodeIterator iter) { - - return null; - } - - private ClassIndex parseClassInfex(ByteCodeIterator iter) { - - return null; - - } - - private ConstantPool parseConstantPool(ByteCodeIterator iter) { - - return null; - } - - -} +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..ba5f7848d1 --- /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 4ac0698801..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,5 +1,7 @@ package com.coderising.jvm.test; +import java.util.List; + import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -12,7 +14,9 @@ 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; @@ -196,7 +200,78 @@ public void testClassIndex(){ 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); + } }