From 648b1197a62ec3235188917df791c74a34c293dc Mon Sep 17 00:00:00 2001 From: kai Date: Fri, 17 Mar 2017 15:05:49 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group06/1378560653/.classpath | 1 + group06/1378560653/article.txt | 3 +- .../coderising/litestruts/Configuration.java | 113 ++++++++++++++++ .../litestruts/ConfigurationException.java | 21 +++ .../litestruts/ConfigurationTest.java | 50 +++++++ .../coderising/litestruts/LoginAction.java | 4 +- .../coderising/litestruts/ReflectionUtil.java | 123 ++++++++++++++++++ .../litestruts/ReflectionUtilTest.java | 111 ++++++++++++++++ .../src/com/coderising/litestruts/Struts.java | 52 +++++--- .../{StructsTest.java => StrutsTest.java} | 4 +- .../litestruts/{structs.xml => struts.xml} | 4 +- 11 files changed, 458 insertions(+), 28 deletions(-) create mode 100644 group06/1378560653/src/com/coderising/litestruts/Configuration.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java rename group06/1378560653/src/com/coderising/litestruts/{StructsTest.java => StrutsTest.java} (97%) rename group06/1378560653/src/com/coderising/litestruts/{structs.xml => struts.xml} (67%) diff --git a/group06/1378560653/.classpath b/group06/1378560653/.classpath index 3e0fb272a8..036cc56d25 100644 --- a/group06/1378560653/.classpath +++ b/group06/1378560653/.classpath @@ -3,5 +3,6 @@ + diff --git a/group06/1378560653/article.txt b/group06/1378560653/article.txt index 478dde01b7..7acf80e1b2 100644 --- a/group06/1378560653/article.txt +++ b/group06/1378560653/article.txt @@ -1,3 +1,4 @@ ��һƪ���£�http://blog.csdn.net/raymond120/article/details/57415472 �ڶ�ƪ���£�http://blog.csdn.net/raymond120/article/details/58043040 -����ƪ���£�http://blog.csdn.net/raymond120/article/details/60759278 \ No newline at end of file +����ƪ���£�http://blog.csdn.net/raymond120/article/details/60759278 +����ƪ���£�http://blog.csdn.net/raymond120/article/details/61937892 \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/litestruts/Configuration.java b/group06/1378560653/src/com/coderising/litestruts/Configuration.java new file mode 100644 index 0000000000..6ae4adeed6 --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/Configuration.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; + +public class Configuration { + + Map actions = new HashMap<>(); + + public Configuration(String fileName) { + + String packageName = this.getClass().getPackage().getName(); + + packageName = packageName.replace('.', '/'); + + InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + private void parseXML(InputStream is){ + + SAXBuilder builder = new SAXBuilder(); + + try { + + Document doc = builder.build(is); + + Element root = doc.getRootElement(); + + for(Element actionElement : root.getChildren("action")){ + + String actionName = actionElement.getAttributeValue("name"); + String clzName = actionElement.getAttributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, clzName); + + for(Element resultElement : actionElement.getChildren("result")){ + + String resultName = resultElement.getAttributeValue("name"); + String viewName = resultElement.getText().trim(); + + ac.addViewResult(resultName, viewName); + + } + + this.actions.put(actionName, ac); + } + + + } catch (JDOMException e) { + throw new ConfigurationException(e); + + } catch (IOException e) { + throw new ConfigurationException(e); + + } + + + } + + public String getClassName(String action) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getClassName(); + } + + public String getResultView(String action, String resultName) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getViewName(resultName); + } + + private static class ActionConfig{ + + String name; + String clzName; + Map viewResult = new HashMap<>(); + + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + public String getClassName(){ + return clzName; + } + public void addViewResult(String name, String viewName){ + viewResult.put(name, viewName); + } + public String getViewName(String resultName){ + return viewResult.get(resultName); + } + } + +} diff --git a/group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java b/group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..97e286827f --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +import java.io.IOException; + +import org.jdom2.JDOMException; + +public class ConfigurationException extends RuntimeException { + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } + +} diff --git a/group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java b/group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..734649f37a --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.coderising.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ConfigurationTest { + + + Configuration cfg = new Configuration("struts.xml"); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetClassName() { + + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName); + + + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName); + } + + @Test + public void testGetResultView(){ + String jsp = cfg.getResultView("login","success"); + Assert.assertEquals("/jsp/homepage.jsp", jsp); + + jsp = cfg.getResultView("login","fail"); + Assert.assertEquals("/jsp/showLogin.jsp", jsp); + + jsp = cfg.getResultView("logout","success"); + Assert.assertEquals("/jsp/welcome.jsp", jsp); + + jsp = cfg.getResultView("logout","error"); + Assert.assertEquals("/jsp/error.jsp", jsp); + + } + +} diff --git a/group06/1378560653/src/com/coderising/litestruts/LoginAction.java b/group06/1378560653/src/com/coderising/litestruts/LoginAction.java index 76547ac3b3..52a9b71cfb 100644 --- a/group06/1378560653/src/com/coderising/litestruts/LoginAction.java +++ b/group06/1378560653/src/com/coderising/litestruts/LoginAction.java @@ -2,7 +2,7 @@ /** * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。 - * @author liuxin + * @author * */ public class LoginAction{ @@ -36,4 +36,4 @@ public void setPassword(String password){ public String getMessage(){ return this.message; } -} \ No newline at end of file +} diff --git a/group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..dda2eec6dd --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.coderising.litestruts; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + + return getMethods(clz,"set"); + + } + + public static void setParameters(Object o, Map params) { + + List methods = getSetterMethods(o.getClass()); + + for(String name : params.keySet() ){ + + String methodName = "set" + name; + + for(Method m: methods){ + + if(m.getName().equalsIgnoreCase(methodName)){ + try { + m.invoke(o, params.get(name)); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz,"get"); + } + + private static List getMethods(Class clz, String startWithName){ + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith(startWithName)){ + + methods.add(m); + + } + + } + + return methods; + } + + public static Map getParameterMap(Object o) { + + Map params = new HashMap<>(); + + List methods = getGetterMethods(o.getClass()); + + for(Method m : methods){ + + String methodName = m.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); + try { + Object value = m.invoke(o); + params.put(name, value); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + + e.printStackTrace(); + } + } + + return params; + } + + ////////////////////////Backup /////////////////////////////////// + + public static List getGetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("get")){ + + methods.add(m); + + } + + } + + return methods; + } + + public static List getSetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("set")){ + + methods.add(m); + + } + + } + + return methods; + + } + + + + +} diff --git a/group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..af378808c6 --- /dev/null +++ b/group06/1378560653/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,111 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ReflectionUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetSetterMethod() throws Exception { + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception{ + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap(); + params.put("name", "test"); + params.put("password", "1234"); + + ReflectionUtil.setParameters(o,params); + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + f = clz.getDeclaredField("password"); + f.setAccessible(true); + Assert.assertEquals("1234", f.get(o)); + + } + + @Test + public void testGetGetterMethod() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getMessage"); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testGetParameters() throws Exception { + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + + LoginAction action = (LoginAction) clz.newInstance(); + action.setName("test"); + action.setPassword("123456"); + + Map params = ReflectionUtil.getParameterMap(action); + + Assert.assertEquals(3, params.size()); + + + Assert.assertEquals(null, params.get("message")); + Assert.assertEquals("test", params.get("name")); + Assert.assertEquals("123456", params.get("password")); + } + +} diff --git a/group06/1378560653/src/com/coderising/litestruts/Struts.java b/group06/1378560653/src/com/coderising/litestruts/Struts.java index 0e73017f99..885c604940 100644 --- a/group06/1378560653/src/com/coderising/litestruts/Struts.java +++ b/group06/1378560653/src/com/coderising/litestruts/Struts.java @@ -1,31 +1,26 @@ package com.coderising.litestruts; -import java.io.IOException; +import java.lang.reflect.Method; import java.util.Map; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; public class Struts { + private final static Configuration cfg = new Configuration("struts.xml"); + public static View runAction(String actionName, Map parameters) { /* 0. 读取配置文件struts.xml - 1. 根据actionName找到相对应的class , 例如LoginAction,通过反射实例化(创建对象) + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , "password"="1234") , 那就应该调用 setName和setPassword方法 - 2. 通过反射调用对象的exectue方法, 并获得返回值,例如"success" + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , @@ -35,22 +30,37 @@ public static View runAction(String actionName, Map parameters) { 放到View对象的jsp字段中。 */ + + String clzName = cfg.getClassName(actionName); + + if(clzName == null){ + return null; + } - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse("structs.xml"); - NodeList actionList = document.getElementsByTagName("action"); + + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + + ReflectionUtil.setParameters(action, parameters); + + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String)m.invoke(action); + + Map params = ReflectionUtil.getParameterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + + + + } catch (Exception e) {//得处理这个异常 - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { e.printStackTrace(); } - return null; } -} \ No newline at end of file +} diff --git a/group06/1378560653/src/com/coderising/litestruts/StructsTest.java b/group06/1378560653/src/com/coderising/litestruts/StrutsTest.java similarity index 97% rename from group06/1378560653/src/com/coderising/litestruts/StructsTest.java rename to group06/1378560653/src/com/coderising/litestruts/StrutsTest.java index 4e761b0b2d..a44021cacc 100644 --- a/group06/1378560653/src/com/coderising/litestruts/StructsTest.java +++ b/group06/1378560653/src/com/coderising/litestruts/StrutsTest.java @@ -7,7 +7,7 @@ import org.junit.Test; -public class StructsTest { +public class StrutsTest { @Test public void testLoginActionSuccess() { @@ -37,4 +37,4 @@ public void testLoginActionFailed() { Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp()); Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message")); } -} \ No newline at end of file +} diff --git a/group06/1378560653/src/com/coderising/litestruts/structs.xml b/group06/1378560653/src/com/coderising/litestruts/struts.xml similarity index 67% rename from group06/1378560653/src/com/coderising/litestruts/structs.xml rename to group06/1378560653/src/com/coderising/litestruts/struts.xml index dd598a3664..e5d9aebba8 100644 --- a/group06/1378560653/src/com/coderising/litestruts/structs.xml +++ b/group06/1378560653/src/com/coderising/litestruts/struts.xml @@ -1,10 +1,10 @@ - + /jsp/homepage.jsp /jsp/showLogin.jsp - + /jsp/welcome.jsp /jsp/error.jsp From ebdc769626caff6a70dd8e237370f2ddfc4e0e1e Mon Sep 17 00:00:00 2001 From: kai Date: Sat, 1 Apr 2017 00:22:40 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group06/1378560653/article.txt | 3 +- .../src/com/coderising/array/ArrayUtil.java | 212 ------------ .../coderising/download/DownloadThread.java | 40 +++ .../coderising/download/FileDownloader.java | 131 ++++++++ .../coderising/download/api/Connection.java | 23 ++ .../download/api/ConnectionException.java | 9 + .../download/api/ConnectionManager.java | 10 + .../download/api/DownloadListener.java | 5 + .../download/impl/ConnectionImpl.java | 96 ++++++ .../download/impl/ConnectionManagerImpl.java | 15 + .../jvm/loader/ClassFileLoader.java | 34 ++ .../jvm/test/ClassFileloaderTest.java | 88 +++++ .../com/coderising/jvm/test/EmployeeV1.java | 27 ++ .../src/com/coding/basic/Queue.java | 2 + .../src/com/coding/basic/Stack.java | 2 + .../coding/basic/{ => array}/ArrayList.java | 5 +- .../src/com/coding/basic/array/ArrayUtil.java | 262 +++++++++++++++ .../com/coding/basic/array/ArrayUtilTest.java | 150 +++++++++ .../coding/basic/linklist/LRUPageFrame.java | 154 +++++++++ .../basic/linklist/LRUPageFrameTest.java | 31 ++ .../basic/{ => linklist}/LinkedList.java | 303 +++++++++++------ .../coding/basic/linklist/LinkedListTest.java | 309 ++++++++++++++++++ 22 files changed, 1597 insertions(+), 314 deletions(-) delete mode 100644 group06/1378560653/src/com/coderising/array/ArrayUtil.java create mode 100644 group06/1378560653/src/com/coderising/download/DownloadThread.java create mode 100644 group06/1378560653/src/com/coderising/download/FileDownloader.java create mode 100644 group06/1378560653/src/com/coderising/download/api/Connection.java create mode 100644 group06/1378560653/src/com/coderising/download/api/ConnectionException.java create mode 100644 group06/1378560653/src/com/coderising/download/api/ConnectionManager.java create mode 100644 group06/1378560653/src/com/coderising/download/api/DownloadListener.java create mode 100644 group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java create mode 100644 group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java create mode 100644 group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java create mode 100644 group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java create mode 100644 group06/1378560653/src/com/coderising/jvm/test/EmployeeV1.java rename group06/1378560653/src/com/coding/basic/{ => array}/ArrayList.java (95%) create mode 100644 group06/1378560653/src/com/coding/basic/array/ArrayUtil.java create mode 100644 group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java rename group06/1378560653/src/com/coding/basic/{ => linklist}/LinkedList.java (52%) create mode 100644 group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java diff --git a/group06/1378560653/article.txt b/group06/1378560653/article.txt index 7acf80e1b2..42b64998ea 100644 --- a/group06/1378560653/article.txt +++ b/group06/1378560653/article.txt @@ -1,4 +1,5 @@ ��һƪ���£�http://blog.csdn.net/raymond120/article/details/57415472 �ڶ�ƪ���£�http://blog.csdn.net/raymond120/article/details/58043040 ����ƪ���£�http://blog.csdn.net/raymond120/article/details/60759278 -����ƪ���£�http://blog.csdn.net/raymond120/article/details/61937892 \ No newline at end of file +����ƪ���£�http://blog.csdn.net/raymond120/article/details/61937892 +����ƪ���£�http://blog.csdn.net/raymond120/article/details/68665071 \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/array/ArrayUtil.java b/group06/1378560653/src/com/coderising/array/ArrayUtil.java deleted file mode 100644 index 2542d4336d..0000000000 --- a/group06/1378560653/src/com/coderising/array/ArrayUtil.java +++ /dev/null @@ -1,212 +0,0 @@ -package com.coderising.array; - -public class ArrayUtil { - - /** - * 给定一个整形数组a , 对该数组的值进行置换 - 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] - 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7] - * @param origin - * @return - */ - public void reverseArray(int[] origin){ - //一定要判断边界条件 - if(origin == null || origin.length == 0){ - return; - } - int N = origin.length; - for(int i = 0; i < N/2; i++){ - int temp = origin[i]; - origin[i] = origin[N-i-1]; - origin[N-i-1] = temp; - } - } - - /** - * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} - * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: - * {1,3,4,5,6,6,5,4,7,6,7,5} - * @param oldArray - * @return - */ - - public int[] removeZero(int[] oldArray){ - int N = oldArray.length; - int[] newArray = new int[N]; - int j = 0; - for(int i = 0; i < N; i++){ - if(oldArray[i] != 0){ - newArray[j] = oldArray[i]; - j++; - } - } - return newArray; - } - - /** - * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 - * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复 - * @param array1 - * @param array2 - * @return - */ - - public int[] merge(int[] array1, int[] array2){ - int N = array1.length + array2.length; - int[] array3 = new int[N]; - System.arraycopy(array1, 0, array3, 0, array1.length); - for(int i = 0; i < N; i++){ - for(int j = 0; j < array2.length; j++){ - if(array3[i] > array2[j]){ - System.arraycopy(array3, i , array3, i+1, N-i-1); - array3[i] = array2[j]; - } - } - } - return array3; - } - /** - * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size - * 注意,老数组的元素在新数组中需要保持 - * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为 - * [2,3,6,0,0,0] - * @param oldArray - * @param size - * @return - */ - public int[] grow(int [] oldArray, int size){ - int[] newArray = new int[oldArray.length + size]; - System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); - return newArray; - } - - /** - * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 - * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13] - * max = 1, 则返回空数组 [] - * @param max - * @return - */ - public int[] fibonacci(int max){ - int[] zero = new int[0]; - int[] array = new int[100]; - array[0] = 1; - array[1] = 1; - int i = 1; - - if(max == 1){ - return zero; - }else{ - while(array[i] <= max){ - i++; - if(i > array.length){ - grow(array, i*2); - } - array[i+1] = array[i] + array[i-1]; - } - return array; - } - } - - /** - * 返回小于给定最大值max的所有素数数组 - * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] - * @param max - * @return - */ - public int[] getPrimes(int max){ - boolean[] prime = new boolean[max + 1]; - int[] zero = new int[0]; - int[] array = new int[max]; - int q = 1; - if(max == 1 || max ==2){ - return zero; - }else{ - for(int i = 3; i < max; i++) - if(i % 2 == 0){ - prime[i] = false; - }else{ - prime[i] = true; - } - - for(int i = 3; i < Math.sqrt(max); i++){//因子;若n是合数,则其所有因子都不超过sqrt(n) - if(prime[i]) - for(int j = 2 * i; j<= max; j += i){//其倍数 - prime[j] = false; - } - } - array[0] = 2; - for(int p = 0; p < max; p++){ - if(prime[p] == true){ - array[q] = p; - q++; - } - } - return array; - } - } - /*int[] zero = new int[0]; - int[] array = new int[100]; - int k = 0; - - if(max == 1 || max == 2){ - return zero; - }else{ - for(int n = 2; n <= max; n++){ - int isPrime = 1; - for(int i = 2; i < n; i++){ - if(n % i == 0){ - isPrime = 0; - break; - } - if(isPrime == 1){ - array[k] = n; - k++; - } - } - } - return array; - }*/ - - /** - * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 - * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 - * @param max - * @return - */ - public int[] getPerfectNumbers(int max){ - int[] perfectNumbers = new int[max]; - int n = 0; - for(int i = 1; i < max; i++){//i:要判断的数 - int sum = 0; - for(int j = 1; j < i; j++){//j:可能因子 - if(i % j == 0){ - sum += j; - } - } - if(sum == i){ - perfectNumbers[n] = i; - n++; - } - } - return perfectNumbers; - } - - /** - * 用seperator 把数组 array给连接起来 - * 例如array= [3,8,9], seperator = "-" - * 则返回值为"3-8-9" - * @param array - * @param s - * @return - */ - public String join(int[] array, String seperator){ - String s = ""; - for(int i = 0; i < array.length; i++){ - s = s + array[i] + seperator; - } - return s; - } - - -} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/download/DownloadThread.java b/group06/1378560653/src/com/coderising/download/DownloadThread.java new file mode 100644 index 0000000000..fd0fc27001 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/DownloadThread.java @@ -0,0 +1,40 @@ +package com.coderising.download; + +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; + +public class DownloadThread extends Thread{ + + Connection conn; + int startPos; + int endPos; + String localFile; + CyclicBarrier barrier; + + public DownloadThread( Connection conn, int startPos, int endPos, String localFile, CyclicBarrier barrier){ + + this.conn = conn; + this.startPos = startPos; + this.endPos = endPos; + this.localFile = localFile; + this.barrier = barrier; + } + + public void run(){ + + try { + System.out.println("Begin to read [" + startPos + "-" + endPos + "]"); + byte[] data = conn.read(startPos, endPos); + RandomAccessFile file = new RandomAccessFile(localFile, "rw"); + file.seek(startPos); + file.write(data); + file.close(); + conn.close(); + barrier.await();//等待别的线程完成 + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/download/FileDownloader.java b/group06/1378560653/src/com/coderising/download/FileDownloader.java new file mode 100644 index 0000000000..5a260a365b --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/FileDownloader.java @@ -0,0 +1,131 @@ +package com.coderising.download; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionManager; +import com.coderising.download.api.DownloadListener; + +public class FileDownloader { + + private String url; + private String localFile; + + DownloadListener listener; + + ConnectionManager cm; + + private static final int DOWNLOAD_THREAD_NUM = 3; + + public FileDownloader(String _url, String localFile) { + this.url = _url; + this.localFile = localFile; + + } + + public void execute(){ + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 + + // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。 + /* + * CyclicBarrier类的用法: + * 当多个线程需要互相等待,直到所有线程跨过某个“屏障”的时候,用这个类 + */ + CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_THREAD_NUM, new Runnable(){ + public void run(){ + listener.notifyFinished(); + } + }) ; + + Connection conn = null; + + try { + + conn = cm.open(this.url); + + int length = conn.getContentLength(); + + createPlaceHolderFile(this.localFile, length); //占位子 + + int[][] ranges = allocateDownloadRange(DOWNLOAD_THREAD_NUM, length);//分配每个线程的下载长度 + + for(int i = 0; i < DOWNLOAD_THREAD_NUM;i++){ + + DownloadThread thread = new DownloadThread( + cm.open(url), + ranges[i][0], + ranges[i][1], + localFile, + barrier); + thread.start(); + } + + } catch (Exception e) { + e.printStackTrace(); + }finally{ + if(conn != null){ + conn.close(); + } + } + + } + + private int[][] allocateDownloadRange(int threadNum, int contentLen) { + int[][] ranges = new int[threadNum][2]; + + int eachThreadSize = contentLen / threadNum; + int left = contentLen % threadNum; + + for(int i = 0; i < threadNum; i++){ + int startPos = i * threadNum; + + int endPos = (i + 1) * eachThreadSize - 1; + + if((i == (threadNum - 1))){ + endPos += left; + } + ranges[i][0] = startPos; + ranges[i][1] = endPos; + } + return ranges; + } + + private void createPlaceHolderFile(String fileName, int contentLen) throws IOException { + + RandomAccessFile file = new RandomAccessFile(fileName, "rw");//以读写方式 + + for(int i = 0; i < contentLen; i++){ + file.write(0); + } + + file.close(); + + } + + public void setListener(DownloadListener listener) { + this.listener = listener; + } + + + + public void setConnectionManager(ConnectionManager ucm){ + this.cm = ucm; + } + + public DownloadListener getListener(){ + return this.listener; + } + +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/download/api/Connection.java b/group06/1378560653/src/com/coderising/download/api/Connection.java new file mode 100644 index 0000000000..0957eaf7f4 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/api/Connection.java @@ -0,0 +1,23 @@ +package com.coderising.download.api; + +import java.io.IOException; + +public interface Connection { + /** + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 + * @return + */ + public byte[] read(int startPos,int endPos) throws IOException; + /** + * 得到数据内容的长度 + * @return + */ + public int getContentLength(); + + /** + * 关闭连接 + */ + public void close(); +} diff --git a/group06/1378560653/src/com/coderising/download/api/ConnectionException.java b/group06/1378560653/src/com/coderising/download/api/ConnectionException.java new file mode 100644 index 0000000000..505f61e224 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/api/ConnectionException.java @@ -0,0 +1,9 @@ +package com.coderising.download.api; + +public class ConnectionException extends Exception { + + public ConnectionException(Exception e) { + super(e); + } + +} diff --git a/group06/1378560653/src/com/coderising/download/api/ConnectionManager.java b/group06/1378560653/src/com/coderising/download/api/ConnectionManager.java new file mode 100644 index 0000000000..0a625bf472 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/api/ConnectionManager.java @@ -0,0 +1,10 @@ +package com.coderising.download.api; + +public interface ConnectionManager { + /** + * 给定一个url , 打开一个连接 + * @param url + * @return + */ + public Connection open(String url) throws ConnectionException; //得到一个Connection的实例 +} diff --git a/group06/1378560653/src/com/coderising/download/api/DownloadListener.java b/group06/1378560653/src/com/coderising/download/api/DownloadListener.java new file mode 100644 index 0000000000..bf9807b307 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/api/DownloadListener.java @@ -0,0 +1,5 @@ +package com.coderising.download.api; + +public interface DownloadListener { + public void notifyFinished(); +} diff --git a/group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java b/group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java new file mode 100644 index 0000000000..643984ee73 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/impl/ConnectionImpl.java @@ -0,0 +1,96 @@ +package com.coderising.download.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; + + +//非public class,仅包内可见,依靠ConnectionMangerImpl实现 +class ConnectionImpl implements Connection { + + URL url; + static final int BUFFER_SIZE = 1024; + + ConnectionImpl(String _url) throws ConnectionException { + try { + this.url = new URL(_url); + } catch (MalformedURLException e) { + throw new ConnectionException(e); + } + } + + /* + * 分段读取数据 + * @see com.coderising.download.api.Connection#read(int, int) + */ + @Override + public byte[] read(int startPos, int endPos) throws IOException { + + /* + * HttpURLConnection是基于HTTP协议的,HttpURLConnection的对象不能直接构造,需要通过url.openConnection()来获得HttpURLConnection对象 + * 示例如下: + * String slurl = "http://...."; + * URL url = new URL(slurl); + * HttpURLConnection httpCoon = (HttpURLConnection) url.openConnection(); + * 调用HttpURLConnection连接对象的getInputStream()函数,将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端 + */ + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + httpConn.setRequestProperty("Range","bytes=" + startPos + "-" + endPos); //只发一个特定的片段,比is.skip有效 + InputStream is = httpConn.getInputStream();// 注意,实际发送请求的代码段就在这里 -------------------------------输入流 + + //is.skip(startPos);//跳过startPos之前的内容 + + byte[] buff = new byte[BUFFER_SIZE]; + int totalLen = endPos - startPos + 1; //注意+1 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节数组流, 可以捕获内存缓冲区的数据,转换成字节数组。----输出流 + + while(baos.size() < totalLen){ + + int len = is.read(buff);//从输入流中读取数据到buff数组,同时返回读取长度,每次读取量小于等于1024 + if (len < 0){ + break; + } + baos.write(buff, 0, len);//buff数组中的数据写入输出流 + } + + if(baos.size() > totalLen){ + byte[] data = baos.toByteArray(); + return Arrays.copyOf(data, totalLen); + } + + return baos.toByteArray(); + } + + /* + * 获取资源长度 + * @see com.coderising.download.api.Connection#getContentLength() + */ + @Override + public int getContentLength() { + URLConnection con; + try { + con = url.openConnection(); + + return con.getContentLength(); + } catch (IOException e) { + e.printStackTrace(); + } + + return -1; + } + + @Override + public void close() { + + + } + +} diff --git a/group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java new file mode 100644 index 0000000000..bdd7d3f8e9 --- /dev/null +++ b/group06/1378560653/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -0,0 +1,15 @@ +package com.coderising.download.impl; + +import com.coderising.download.api.Connection; +import com.coderising.download.api.ConnectionException; +import com.coderising.download.api.ConnectionManager; + +public class ConnectionManagerImpl implements ConnectionManager { + + @Override + public Connection open(String url) throws ConnectionException { + + return new ConnectionImpl(url); + } + +} diff --git a/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java b/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..24c2870d17 --- /dev/null +++ b/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -0,0 +1,34 @@ +package com.coderising.jvm.loader; + +import java.util.ArrayList; +import java.util.List; + + + +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + + return null; + + + } + + + public void addClassPath(String path) { + + } + + + + public String getClassPath(){ + return null; + } + + + + + +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..bed3e233e1 --- /dev/null +++ b/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,88 @@ +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 array2[j]){ + newArray[count++] = array2[j++]; + }else if(array1[i] == array2[j]){ + newArray[count++] = array2[j++]; + i++; + } + } + + while(i==array1.length && j= max){ + break; + }else{ + count++; + } + } + + return Arrays.copyOf(a,count); + } + + /** + * 返回小于给定最大值max的所有素数数组 + * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19] + * @param max + * @return + */ + public int[] getPrimes(int max){ + if(max < 3){ + return new int[0]; + } + + boolean[] isPrime = isPrime(max); + + int[] array = new int[max]; + int count = 1; + array[0] = 2; + for(int i = 3; i < max; i++){ + if(isPrime[i]){ + array[count++] = i; + } + } + return Arrays.copyOf(array, count); + } + + private boolean[] isPrime(int max) { + boolean[] isPrime = new boolean[max]; + for(int i = 3; i < max; i++){ + if(i % 2 != 0 ){ + isPrime[i] = true; + }else{ + isPrime[i] = false; + } + } + + for(int i = 3; i < Math.sqrt(max); i++){ + if(isPrime[i]){ + for(int j = 2*i ; j < max; j += i){ + isPrime[j] = false; + } + } + } + return isPrime; + } + + /** + * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 + * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数 + * @param max + * @return + */ + public int[] getPerfectNumbers(int max){ + if(max < 0){ + return new int[0]; + } + + int[] Array = new int[max]; + + int count = 0; + for(int n = 1; n < max; n++) + { + int sum = 0; + for(int i=1; i< n; i++) + { + if(n%i == 0) + sum += i; + } + if(sum == n) + Array[count++] = n; + } + + return Arrays.copyOf(Array, count); + } + + /** + * 用seperator 把数组 array给连接起来 + * 例如array= [3,8,9], seperator = "-" + * 则返回值为"3-8-9" + * @param array + * @param s + * @return + */ + public String join(int[] array, String seperator) + { + if(array == null || array.length == 0){ + return ""; + } + + StringBuilder buffer = new StringBuilder(); + + for(int i = 0; i < array.length; i++){ + buffer.append(array[i]); + if(i < array.length - 1){ + buffer.append(seperator); + } + } + + return buffer.toString(); + } +} diff --git a/group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java b/group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java new file mode 100644 index 0000000000..0513b8e05f --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/array/ArrayUtilTest.java @@ -0,0 +1,150 @@ +package com.coding.basic.array; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ArrayUtilTest { + + private ArrayUtil myArray; + + @Before + public void setUp() throws Exception{ + myArray = new ArrayUtil(); + } + + @Test + public void testReverseArray() + { + int[] a = {1, 2, 1, 3, 5, 6}; + int[] b = {6, 5, 3, 1, 2, 1}; + + myArray.reverseArray(a); + assertArrayEquals(a, b); + + int[] c = new int[0]; + myArray.reverseArray(c); + assertArrayEquals(c, new int[0]); + + } + + @Test + public void testRemoveZero() + { + int[] oldArr= {1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 1, 2, 0, 5}; + int b[] = {1, 3, 4, 5, 6, 6, 5, 4, 7, 6, 7, 1, 2, 5}; + int[] c = myArray.removeZero(oldArr); + assertArrayEquals(b, c); + + int[] d = null; + int[] e = myArray.removeZero(d); + assertNull(e); + + } + + @Test + public void testMerge() + { + int a1[] = {1, 2, 3, 4, 5}; + int b1[] = {3, 4, 5, 6, 7, 8}; + int c1[] = {1, 2, 3, 4, 5, 6, 7, 8}; + int[] newArray1 = myArray.merge(a1, b1); + assertArrayEquals(c1, newArray1); + + int a2[] = new int[0]; + int b2[] = {0, 2, 3, 6, 7, 8}; + int c2[] = {0, 2, 3, 6, 7, 8}; + int[] newArray2 = myArray.merge(a2, b2); + assertArrayEquals(c2, newArray2); + + int a3[] = {0, 2, 3, 6, 7, 8}; + int b3[] = new int[0]; + int c3[] = {0, 2, 3, 6, 7, 8}; + int[] newArray3 = myArray.merge(a3, b3); + assertArrayEquals(c3, newArray3); + + int[] a4 = null; + int[] b4 = null; + int[] newArray4 = myArray.merge(a4, b4); + assertNull(newArray4); + } + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public void testGrow() + { + int[] a = {3, 5, 7, 8, 9}; + int[] b = {3, 5, 7, 8, 9, 0, 0, 0}; + int[] newArray = myArray.grow(a, 3); + assertArrayEquals(b, newArray); + + int[] c = null; + int[] newArray1 = myArray.grow(c, 3); + assertNull(newArray1); + + // size < 0 抛出异常 + expectedEx.expect(Exception.class); + myArray.grow(a, -3);//注意这里 + } + + @Test + public void testFibonacci() + { + //max == 1时返回空数组 + int[] array1 = myArray.fibonacci(1); + int[] b = new int[0]; + assertArrayEquals(array1, b); + + + int[] array2= myArray.fibonacci(35); + int[] c = {1, 1, 2, 3, 5, 8, 13, 21, 34 }; + assertArrayEquals(c, array2); + } + + @Test + public void testGetPrimes() + { + int[] a = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 }; + int[] array1 = myArray.getPrimes(35); + assertArrayEquals(a, array1); + + //max <= 2的时候没有素数,数组为空数组 + int[] array2 = myArray.getPrimes(1); + int[] b = new int[0]; + assertArrayEquals(array2, b); + } + + @Test + public void testGetPerfectNumbers() + { + int[] array = myArray.getPerfectNumbers(10000); + int[] a = {6, 28, 496, 8128 }; + assertArrayEquals(a, array); + } + + @Test + public void testJoin() + { + int[] Array0 = {3, 5, 7, 8, 9}; + String s0 = myArray.join(Array0, "-"); + String s1 = "3-5-7-8-9"; + assertEquals(s1, s0); + + int[] Array1 = {3}; + String s2 = myArray.join(Array1, "-"); + String s3 = "3"; + assertEquals(s2, s3); + + //传递空数组时,返回空字符串 + int[] Array2 = new int[0]; + String s4 = myArray.join(Array2, "-"); + String s5 = ""; + assertEquals(s4, s5); + } +} + diff --git a/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java new file mode 100644 index 0000000000..75f3002227 --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrame.java @@ -0,0 +1,154 @@ +package com.coding.basic.linklist; + +/** + * 用双向链表实现LRU算法 + * + */ +public class LRUPageFrame { + + private static class Node { + + Node prev; + Node next; + int pageNum; + + Node(int pageNum) { + this.pageNum = pageNum; + } + } + + private int capacity;//容量 + + private Node first; // 链表头 + private Node last; // 链表尾 + + + public LRUPageFrame(int capacity) { + this.capacity = capacity; + } + + /** + * 获取缓存中对象 + * + * @param key + * @return + */ + public void access(int pageNum) { + if(capacity == 0){ + return; + } + + Node node = new Node(pageNum); + + //填满:从后往前填满 + if(!isFull()){ + if(first == null && last == null){ + first = node; + last = node; + first.prev = null; + last.prev = null; + } else { + first.prev = node; + node.next = first; + first = node; + } + } else { + if(!isFind(pageNum)){ + first.prev = node; + node.next = first; + first = node; + last = last.prev; + last.next = null; + } else { + Node pNode = first; + if(first.pageNum == pageNum){ + return; + } + + //注意:while循环只是遍历了1~last.prev的节点 + while(pNode.next != null){ + if(pNode.pageNum == pageNum){ + pNode.next.prev = pNode.prev; + pNode.prev.next = pNode.next; + pNode.next = first; + first.prev = pNode; + first = pNode; + break; + } + pNode = pNode.next; + } + + if(last.pageNum == pageNum){ + last.next = first; + first.prev = last; + first = last; + last = last.prev; + last.next = null; + } + } + } + + } + + private boolean isFind(int pageNum) { + Node pNode = first; + while(pNode != null){ + if(pNode.pageNum == pageNum){ + return true; + } + pNode = pNode.next; + } + return false; + } + + public boolean isFull() { + int count = 0; + Node pNode = first; + while(pNode != null){ + count++; + pNode = pNode.next; + } + + if(count < capacity){ + return false; + } else { + return true; + } + } + + + + public String toString(){ + StringBuilder buffer = new StringBuilder(); + Node node = first; + while(node != null){ + buffer.append(node.pageNum); + + node = node.next; + if(node != null){ + buffer.append(","); + } + } + return buffer.toString(); + } + + public static void main(String args[]){ + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + System.out.println(frame.toString()); + frame.access(2); + System.out.println(frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + frame.access(3); + System.out.println(frame.toString()); + frame.access(0); + System.out.println(frame.toString()); + frame.access(4); + System.out.println(frame.toString()); + } +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java new file mode 100644 index 0000000000..c323d03b3f --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/linklist/LRUPageFrameTest.java @@ -0,0 +1,31 @@ +package com.coding.basic.linklist; + +import org.junit.Assert; + +import org.junit.Test; + + +public class LRUPageFrameTest { + + @Test + public void testAccess() { + LRUPageFrame frame = new LRUPageFrame(3); + frame.access(7); + frame.access(0); + frame.access(1); + Assert.assertEquals("1,0,7", frame.toString()); + frame.access(2); + Assert.assertEquals("2,1,0", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(0); + Assert.assertEquals("0,2,1", frame.toString()); + frame.access(3); + Assert.assertEquals("3,0,2", frame.toString()); + frame.access(0); + Assert.assertEquals("0,3,2", frame.toString()); + frame.access(4); + Assert.assertEquals("4,0,3", frame.toString()); + } + +} \ No newline at end of file diff --git a/group06/1378560653/src/com/coding/basic/LinkedList.java b/group06/1378560653/src/com/coding/basic/linklist/LinkedList.java similarity index 52% rename from group06/1378560653/src/com/coding/basic/LinkedList.java rename to group06/1378560653/src/com/coding/basic/linklist/LinkedList.java index d7b4775f35..22ad1d6070 100644 --- a/group06/1378560653/src/com/coding/basic/LinkedList.java +++ b/group06/1378560653/src/com/coding/basic/linklist/LinkedList.java @@ -1,37 +1,44 @@ -package com.coding.basic; +package com.coding.basic.linklist; +import java.util.Arrays; +import java.util.Stack; +import com.coding.basic.Iterator; +import com.coding.basic.List; public class LinkedList implements List { - private Node head; private int size; + public LinkedList(){ + this.head = null; + this.size = 0; + } + private static class Node { Object data; Node next; - public Node(Object data){ + private Node(Object data){ this.data = data; this.next = null; } } - public LinkedList(){ - this.head = new Node(null); - this.size = 0; - } - public void add(Object o){ - Node newNode = new Node(o); - Node pNode = head; - while(pNode.next != null){ - pNode = pNode.next; + Node node = new Node(o); + if(head == null){ + head = node; + }else{ + Node pNode = head; + while(pNode.next != null){ + pNode = pNode.next; + } + pNode.next = node; } - - pNode.next = newNode; size++; } + public void add(int index , Object o){ checkIndex(index); @@ -59,10 +66,14 @@ public Object get(int index){ } public Object remove(int index){ checkIndex(index); - if(size == 0){ + if(head == null){ return null; } + if(index == 0){ + removeFirst(); + }//忘了考虑这种情况了 + Node node = new Node(null); Node pNode = head; for(int i = 0; i < index; i++){ @@ -72,35 +83,31 @@ public Object remove(int index){ node.next = pNode.next; size--; - return pNode; + return pNode.data; } public int size(){ - Node pNode = head; - while(pNode.next != null){ - pNode = pNode.next; - size++; - } return size; } public void addFirst(Object o){ - if(size == 0){ - head.data = o; - } - Node newNode = new Node(o); - Node pNode = head; - head = newNode; - newNode.next = pNode.next; + + if(head == null){ + head = newNode; + }else{ + newNode.next = head; + head = newNode; + } size++; } + public void addLast(Object o){ - if(size == 0){ - head.data = o; + Node newNode = new Node(o); + if(head == null){ + head = newNode; } - Node newNode = new Node(o); Node pNode = head; while(pNode.next != null){ pNode = pNode.next; @@ -109,8 +116,9 @@ public void addLast(Object o){ newNode.next = null; size++; } + public Object removeFirst(){ - if(size == 0){ + if(head == null){ return null; } @@ -118,10 +126,11 @@ public Object removeFirst(){ head = pNode.next; head.next = pNode.next.next; size--; - return pNode; + return pNode.data; } + public Object removeLast(){ - if(size == 0){ + if(head == null){ return null; } @@ -134,7 +143,7 @@ public Object removeLast(){ node.next = null; size--; - return pNode; + return pNode.data; } public Iterator iterator(){ return new LinkedListIterator(); @@ -169,25 +178,47 @@ public void checkIndex(int index){ * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ - public void reverse(Node head){ - if(head.next == null || head.next.next == null){ + public void reverse(){ + if(head == null){ return; } - Node p = head.next; - Node q = head.next.next; - Node t = null; + Stack s = new Stack<>(); - while(q.next != null){ - t = q.next; - q.next = p; - p = q; - q = t; + Node currentNode = head; + while(currentNode != null){ + s.push(currentNode); + + Node nextNode = currentNode.next; + currentNode.next = null; //把链断开 + currentNode = nextNode; } - head.next.next = null;//设置链表尾部 - head.next = p;//设置链表头部 + head = s.pop(); + + currentNode = head; + while(!s.isEmpty()){ + Node nextNode = s.pop(); + currentNode.next = nextNode; + currentNode = nextNode; + } + } + + /*if(head == null || head.next == null){ + return; + } + + Node next = null;//当前节点的后一个节点 + Node pre = null;//当前节点的前一个节点 + + while(head != null){ + next = head.next; + head.next = pre; + pre = head; + head = next; } + head = pre; + }*/ /** * 删除一个单链表的前半部分 @@ -196,22 +227,15 @@ public void reverse(Node head){ */ public void removeFirstHalf(){ - if(size == 0 || head.next == null || head.next.next == null){ + if(head == null || head.next == null){ return; } - Node pNode = head; - Node node = null; - for(int i = 0; i < size/2; i++){ - node = pNode; - pNode = pNode.next; + for(int i = 0; i <= size/2; i++){ + removeFirst(); + size--; } - if(size %2 == 0){ - head.next = pNode; - }else{ - head.next = node; - } } /** @@ -220,7 +244,7 @@ public void removeFirstHalf(){ * @param length */ public void remove(int i, int length){ - if(size == 0 || head.next == null){ + if(head == null){ return; } @@ -228,6 +252,7 @@ public void remove(int i, int length){ checkIndex(k); remove(k); } + size -= length; } /** * 假定当前链表和list均包含已升序排列的整数 @@ -238,17 +263,21 @@ public void remove(int i, int length){ * @param list */ public int[] getElements(LinkedList list){ - if(list.size == 0 || list == null){ + if(list == null){ return new int[0]; } int[] array = new int[list.size]; - int k = 0; + int count = 0; for(int i = 0; i < list.size; i++){ int index = (int) list.get(i); - array[k] = (int) get(index); + if(index > -1 && index < size){ + array[count] = (int) get(index); + count++; + } } - return array; + + return Arrays.copyOf(array, count); //Arrays.copyOf(a,count)截取数组a的count长度 } /** @@ -258,15 +287,16 @@ public int[] getElements(LinkedList list){ * @param list */ - public void subtract(LinkedList list,LinkedList oldList){ - if(oldList == null || oldList.size ==0 || list == null || list.size == 0){ + public void subtract(LinkedList list){ + if(list == null){ return; } - for(int i = 0; i < oldList.size; i++){ - for(int j = 0; j < list.size; j++){ - if(list.get(j) == oldList.get(i)){ - oldList.remove(i); + for(int i = 0; i < list.size; i++){ + for(int j = 0; j < size; j++){ + if(list.get(i).equals(get(j))){ + remove(j); + size --; } } } @@ -276,20 +306,43 @@ public void subtract(LinkedList list,LinkedList oldList){ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ - public void removeDuplicateValues(LinkedList list){ - if(list == null || list.size == 0){ + public void removeDuplicateValues(){ + if(head == null){ return; } - - int count = 0; - Node pNode = head; - while(pNode.next != null){ - pNode = pNode.next; - count++; - if(pNode.data == pNode.next.data){ - list.remove(count+1); + + for(int i = 0; i < size; i++){ + for(int j = i+1; j < size; j++){ + if(get(i).equals(get(j))){ + remove(j); + size--; + } } } + /*if(head == null){ + throw new RuntimeException("LinkedList is empty!"); + }else{ + Node pre = head; + Node cur = head; + while(cur.next != null){ + cur = cur.next; + Object data = pre.data; + while(cur.data == data){ + if(cur.next == null){ + pre.next = null; + break; + } + pre.next = cur.next; + size--; + cur =cur.next; + if(cur == null){ + break; + } + } + pre = pre.next; + } + } + */ } /** @@ -299,19 +352,25 @@ public void removeDuplicateValues(LinkedList list){ * @param max */ public void removeRange(int min, int max){ - if(size == 0){ + if(head == null){ return; } - int count = 0; - Node pNode = head; - while(pNode.next != null){ - pNode = pNode.next; - count++; - if(min < (int)pNode.data || (int)pNode.data < max){ - remove(count); + Node pre = head; + Node cur = head; + + while(cur.next != null){ + cur = cur.next; + int data = (int)cur.data; + if(data < max && data > min){ + pre.next = cur.next; + cur = cur.next; + } else { + pre = pre.next; + cur = cur.next; } } + } /** @@ -319,24 +378,68 @@ public void removeRange(int min, int max){ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ - public LinkedList intersection( LinkedList list){ - if(list.size == 0){ + public LinkedList intersection(LinkedList list){ + if(head == null || list.size ==0 ){ return null; } - LinkedList listC = new LinkedList(); - Node p = head; - Node q = list.head; + LinkedList result = new LinkedList(); - while(p.next != null){ - p = p.next; - while(q.next !=null){ - q = q.next; - if(p.data.equals(q.data)){ - listC.add(p); - } + int i = 0; + int j = 0; + + while(i < this.size && j < list.size()){ + + int value1 = (int)this.get(i); + int value2 = (int)list.get(j); + + if(value1 == value2){ + result.add(value1); + i++; + j++; + } else if (value1 < value2) { + i++; + } else { + j++; + } + } + return result; + } + + /* + * 为了测试方便,引入toString()方法 + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("["); + Node node = head; + while(node != null){ + buffer.append(node.data); + if(node.next != null){ + buffer.append(","); } + node = node.next; + } + buffer.append("]"); + + return buffer.toString(); + } + + public static void main(String args[]){ + LinkedList list7 = new LinkedList(); + + list7.add(1); + list7.add(2); + list7.add(3); + list7.add(4); + list7.add(5); + list7.add(6); + list7.add(12); + + for(int i = 0; i < list7.size(); i++){ + System.out.println(list7.get(i)); } - return listC; } } + + diff --git a/group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java b/group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java new file mode 100644 index 0000000000..a51e6455b3 --- /dev/null +++ b/group06/1378560653/src/com/coding/basic/linklist/LinkedListTest.java @@ -0,0 +1,309 @@ +package com.coding.basic.linklist; + +import static org.junit.Assert.*; + +import org.junit.Assert; +import org.junit.Test; + + +public class LinkedListTest { + @Test + public void testAdd() { + LinkedList l1 = new LinkedList(); + + Assert.assertEquals("[]", l1.toString()); + + l1.add(1); + l1.add(2); + l1.add(3); + l1.add(4); + + Assert.assertEquals("[1,2,3,4]", l1.toString()); + } + + @Test + public void TestSize(){ + LinkedList l2 = new LinkedList(); + + Assert.assertEquals(0, l2.size()); + + l2.add(1); + l2.add(2); + l2.add(3); + + Assert.assertEquals(3, l2.size()); + } + + @Test + public void testAddIndex(){ + LinkedList l3 = new LinkedList(); + + l3.add(1); + l3.add(2); + l3.add(3); + l3.add(4); + + l3.add(2, 6); + + Assert.assertEquals("[1,2,6,3,4]", l3.toString()); + } + + @Test + public void testGet(){ + LinkedList l4 = new LinkedList(); + l4.add(1); + l4.add(2); + l4.add(3); + l4.add(4); + + Assert.assertEquals(3, l4.get(2)); + } + + @Test + public void testRemove(){ + LinkedList l5 = new LinkedList(); + l5.add(1); + l5.add(2); + l5.add(3); + l5.add(4); + + l5.remove(3); + + Assert.assertEquals("[1,2,3]", l5.toString()); + } + + @Test + public void testAddFirst(){ + LinkedList l6 = new LinkedList(); + + l6.addFirst(1); + + Assert.assertEquals("[1]", l6.toString()); + + l6.add(2); + l6.add(3); + + l6.addFirst(2); + + Assert.assertEquals("[2,1,2,3]", l6.toString()); + } + @Test + public void testAddLast(){ + LinkedList l7 = new LinkedList(); + + l7.addLast(1); + + Assert.assertEquals("[1]", l7.toString()); + + l7.add(2); + l7.add(3); + + l7.addLast(4); + + Assert.assertEquals("[1,2,3,4]", l7.toString()); + } + @Test + public void testRmemoveFirst(){ + LinkedList l8 = new LinkedList(); + + l8.removeFirst(); + + Assert.assertEquals("[]", l8.toString()); + + l8.add(2); + l8.add(3); + + l8.removeFirst(); + + Assert.assertEquals("[3]", l8.toString()); + } + + @Test + public void testRmemoveLast(){ + LinkedList l9 = new LinkedList(); + + l9.removeLast(); + + Assert.assertEquals("[]", l9.toString()); + + l9.add(2); + l9.add(3); + + l9.removeLast(); + + Assert.assertEquals("[2]", l9.toString()); + } + + @Test + public void testReverse(){ + LinkedList list1 = new LinkedList(); + + list1.reverse(); + + Assert.assertEquals("[]", list1.toString()); + + list1.add(1); + list1.add(2); + list1.add(3); + + list1.reverse(); + + Assert.assertEquals("[3,2,1]", list1.toString()); + } + + @Test + public void testRemoveFirstHalf(){ + LinkedList list2 = new LinkedList(); + list2.removeFirstHalf(); + Assert.assertEquals("[]", list2.toString()); + + list2.add(1); + list2.removeFirstHalf(); + Assert.assertEquals("[1]", list2.toString()); + + list2.add(2); + list2.add(3); + list2.add(4); + list2.removeFirstHalf(); + + Assert.assertEquals("[3,4]", list2.toString()); + + list2.add(5); + list2.removeFirstHalf(); + + Assert.assertEquals("[4,5]", list2.toString()); + + } + @Test + public void testRemoveLength(){ + LinkedList list3 = new LinkedList(); + list3.remove(1,3); + Assert.assertEquals("[]", list3.toString()); + + list3.add(1); + list3.add(2); + list3.add(3); + list3.add(4); + list3.add(5); + list3.remove(0,1); + + Assert.assertEquals("[2,3,4,5]", list3.toString()); + } + + @Test + public void testGetElements(){ + LinkedList list4 = new LinkedList(); + LinkedList list = new LinkedList(); + + int[] array = null; + array = list4.getElements(list); + + assertArrayEquals(new int[0], array); + + list4.add(11); + list4.add(101); + list4.add(201); + list4.add(301); + list4.add(401); + list4.add(501); + list4.add(601); + list4.add(701); + list.add(1); + list.add(3); + list.add(12); + list.add(6); + + array = list4.getElements(list); + int[] result = {101,301,601}; + + assertArrayEquals(result, array); + + } + @Test + public void testSubtract(){ + LinkedList list5 = new LinkedList(); + LinkedList list = new LinkedList(); + + list5.subtract(list); + + Assert.assertEquals("[]", list5.toString()); + + list5.add(11); + list5.add(101); + list5.add(201); + list5.add(301); + list5.add(401); + list5.add(501); + list5.add(601); + list5.add(701); + list.add(11); + list.add(301); + list.add(12); + list.add(401); + + list5.subtract(list); + + Assert.assertEquals("[101,201,501,601,701]", list5.toString()); + } + @Test + public void testRemoveDuplicateValues(){ + LinkedList list6 = new LinkedList(); + + list6.removeDuplicateValues(); + + Assert.assertEquals("[]", list6.toString()); + + list6.add(1); + list6.add(2); + list6.add(2); + list6.add(10); + + list6.removeDuplicateValues(); + + Assert.assertEquals("[1,2,10]", list6.toString()); + } + + @Test + public void testRemoveRange(){ + LinkedList list7 = new LinkedList(); + + list7.removeRange(0, 10); + + Assert.assertEquals("[]", list7.toString()); + + list7.add(1); + list7.add(2); + list7.add(3); + list7.add(4); + list7.add(5); + list7.add(6); + list7.add(12); + + list7.removeRange(3, 10); + + Assert.assertEquals("[1,2,12]", list7.toString()); + } + + @Test + public void testIntersection(){ + LinkedList list8 = new LinkedList(); + + list8.add(1); + list8.add(2); + list8.add(3); + list8.add(4); + + LinkedList list9 = new LinkedList(); + list9.add(2); + list9.add(3); + list9.add(4); + list9.add(8); + + LinkedList result = new LinkedList(); + result = list8.intersection(list9); + + Assert.assertEquals("[2,3,4]", result.toString()); + + } +} + From 8ba6ef65aa9f17427276272d6a769cf4235d80d5 Mon Sep 17 00:00:00 2001 From: kai Date: Sun, 2 Apr 2017 01:44:52 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jvm/loader/ClassFileLoader.java | 53 ++++++++++++++----- .../jvm/test/ClassFileloaderTest.java | 7 +-- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java b/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java index 24c2870d17..ff832c8dde 100644 --- a/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group06/1378560653/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -1,5 +1,9 @@ package com.coderising.jvm.loader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -9,26 +13,49 @@ public class ClassFileLoader { private List clzPaths = new ArrayList(); - public byte[] readBinaryCode(String className) { - - return null; - - + public byte[] readBinaryCode(String className) { + String classDirName = className.replace('.', '\\')+".class"; + String clzpath = getClassPath()+"\\"+ classDirName; + try { + FileInputStream clz = new FileInputStream(clzpath); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int flag = 0; + while((flag = clz.read())!=-1){ + baos.write(flag); + } + clz.close(); + return baos.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; } public void addClassPath(String path) { - + File file = new File(path); + if(file.exists()){ + clzPaths.add(path); + } else { + throw new IllegalArgumentException("路径:"+path+"不存在"); + } } - - + public String getClassPath(){ - return null; + if(clzPaths.isEmpty()){ + return " "; + } + + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < clzPaths.size(); i++) { + buf.append(clzPaths.get(i)); + if(i != (clzPaths.size() - 1)){ + buf.append(";"); + } + } + return buf.toString(); } - - - - } \ No newline at end of file diff --git a/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java index bed3e233e1..3ace0974f5 100644 --- a/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java +++ b/group06/1378560653/src/com/coderising/jvm/test/ClassFileloaderTest.java @@ -8,14 +8,11 @@ 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 path1 = "H:\\github\\coding2017\\group06\\1378560653\\bin"; + static String path2 = "C:\\Temp";