diff --git a/.gitignore b/.gitignore
index 8b13789179..156b10d1f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,271 @@
-
+
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+*.publishproj
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+#############
+## Windows detritus
+#############
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac crap
+.DS_Store
+
+
+#############
+## Python
+#############
+
+*.py[cod]
+
+# Packages
+*.egg
+*.egg-info
+dist/
+build/
+eggs/
+parts/
+var/
+sdist/
+develop-eggs/
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
+.gitignore
+=======
+
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#ide config
+.metadata
+.recommenders
+
+
+*.xml
+*.iml
+.idea
+*.iml
+rebel.xml
+rebel-remote.xml
+
+.classpath
+.project
+.setting
+.metadata
+
+target
+*.class
+
+log
+*.log
+tmp
+*.tmp
+
+.metadata
+RemoteSystemsTempFiles
+.gitignore
+
+.recommenders
+.idea/
+*.iml
+rebel.*
+.rebel.*
+
+target
+*.DS_Store
+liuxin/.DS_Store
+liuxin/src/.DS_Store
diff --git a/group01/1298552064/.classpath b/group01/1298552064/.classpath
new file mode 100644
index 0000000000..05cf0dba9e
--- /dev/null
+++ b/group01/1298552064/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/group01/1298552064/.gitignore b/group01/1298552064/.gitignore
new file mode 100644
index 0000000000..4ae0a33837
--- /dev/null
+++ b/group01/1298552064/.gitignore
@@ -0,0 +1,4 @@
+/bin/
+.classpath
+.project
+/src/*.jar
\ No newline at end of file
diff --git a/group01/1298552064/.project b/group01/1298552064/.project
new file mode 100644
index 0000000000..ddbb7719d0
--- /dev/null
+++ b/group01/1298552064/.project
@@ -0,0 +1,17 @@
+
+
+ 1298552064Learning
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/group01/1298552064/src/week01/basic/MyLinkedList.java b/group01/1298552064/src/week01/basic/MyLinkedList.java
index 4894c5ff6c..88db213864 100644
--- a/group01/1298552064/src/week01/basic/MyLinkedList.java
+++ b/group01/1298552064/src/week01/basic/MyLinkedList.java
@@ -124,7 +124,7 @@ public Object removeLast() {
Node p = head;
for (int i = 0; i < size; i++) {
if (p.next.next == null) {
- removeObject = p.next;
+ removeObject = p.next.data;
p.next = null;
break;
} else {
diff --git a/group01/1298552064/src/week02/array/ArrayUtil.java b/group01/1298552064/src/week02/array/ArrayUtil.java
new file mode 100644
index 0000000000..9b6c0bebaf
--- /dev/null
+++ b/group01/1298552064/src/week02/array/ArrayUtil.java
@@ -0,0 +1,245 @@
+package week02.array;
+
+import java.util.Arrays;
+
+public class ArrayUtil {
+
+ // 工具类,不予许创建实例
+ private 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) {
+ int temp = 0;
+
+ // 数组首尾元素置换
+ for (int i = 0; i < origin.length / 2; i++) {
+ temp = origin[i];
+ origin[i] = origin[origin.length - i - 1];
+ origin[origin.length - 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 static int[] removeZero(int[] oldArray) {
+ int[] newArray = null;
+ if (oldArray != null) {
+ newArray = new int[oldArray.length];
+ int size = 0;
+ for (int i = 0; i < oldArray.length; i++) {
+ if (oldArray[i] != 0) {
+ newArray[size] = oldArray[i];
+ size++;
+ }
+ }
+ newArray = Arrays.copyOf(newArray, size);
+ }
+ return newArray;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的 例如 a1 =
+ * [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ *
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public static int[] merge(int[] array1, int[] array2) {
+ int[] newArray = null;
+ if (array1 != null && array2 != null) {
+ int size = 0;
+
+ // index1、index2表示array1和array2数组的比较索引
+ int index1 = 0, index2 = 0;
+ newArray = new int[array1.length + array2.length];
+
+ while (index1 < array1.length && index2 < array2.length) {
+ if (array1[index1] == array2[index2]) {
+ newArray[size++] = array1[index1];
+ index1++;
+ index2++;
+ } else if (array1[index1] < array2[index2]) {
+ // 数组array1去重
+ if (size > 0 && array1[index1] == newArray[size - 1]) {
+ size--;
+ }
+ newArray[size++] = array1[index1];
+ index1++;
+ } else {
+ // 数组array2去重
+ if (size > 0 && array2[index2] == newArray[size - 1]) {
+ size--;
+ }
+ newArray[size++] = array2[index2];
+ index2++;
+ }
+ }
+
+ // 将数组array1剩下的元素放入
+ while (index1 < array1.length) {
+ newArray[size++] = array1[index1++];
+ }
+
+ // 将数组array2剩下的元素放入
+ while (index2 < array2.length) {
+ newArray[size++] = array2[index2++];
+ }
+
+ // 合并后有序数组
+ newArray = Arrays.copyOf(newArray, size);
+ }
+ 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[] newArray = null;
+ if (oldArray != null) {
+ newArray = new int[oldArray.length + size];
+ for (int i = 0; i < oldArray.length; i++) {
+ newArray[i] = oldArray[i];
+ }
+ }
+ return newArray;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列 例如, max = 15 ,
+ * 则返回的数组应该为 [1,1,2,3,5,8,13] max = 1, 则返回空数组 []
+ *
+ * @param max
+ * @return
+ */
+ public static int[] fibonacci(int max) {
+
+ // 计算方法:f(n) = f(n-1) + f(n-2) 采用数组计算
+ int[] result = null;
+ if (max <= 1) {
+ result = new int[] {};
+ } else {
+ int i = 2;
+ result = new int[max];
+ result[0] = result[1] = 1;
+ for (; i < max; i++) {
+ if (result[i - 1] + result[i - 2] < max) {
+ result[i] = result[i - 1] + result[i - 2];
+ } else {
+ break;
+ }
+ }
+ result = Arrays.copyOf(result, i);
+ }
+ return result;
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ *
+ * @param max
+ * @return
+ */
+ public static int[] getPrimes(int max) {
+ int[] newArray = new int[] {};
+ if (max > 2) {
+ newArray = new int[max];
+ int size = 0, j = 0;
+ for (int i = 2; i < max; i++) {
+ for (j = 2; j < i / 2 + 1; j++) {
+ if (i % j == 0) {
+ break;
+ }
+ }
+
+ if (j == i / 2 + 1) {
+ newArray[size++] = i;
+ }
+ }
+ newArray = Arrays.copyOf(newArray, size);
+ }
+ return newArray;
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ *
+ * @param max
+ * @return
+ */
+ public static int[] getPerfectNumbers(int max) {
+ int[] newArray = new int[] {};
+ if (max > 0) {
+ newArray = new int[max];
+ int size = 0, sum = 0;
+ for (int i = 1; i < max; i++) {
+ sum = 0;
+ for (int j = 1; j < i / 2 + 1; j++) {
+ if (i % j == 0) {
+ sum += j;
+ }
+ }
+ if (i == sum) {
+ newArray[size++] = i;
+ }
+ }
+ newArray = Arrays.copyOf(newArray, size);
+ }
+ 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) {
+ String joinResult = null;
+ if (array != null) {
+ joinResult = "";
+ for (int i = 0; i < array.length; i++) {
+ joinResult += array[i] + seperator;
+ }
+ joinResult = joinResult.equals("") ? "" : joinResult.substring(0, joinResult.length() - 1);
+ }
+ return joinResult;
+ }
+
+ public static void main(String[] args) {
+ int[] a = new ArrayUtil().getPerfectNumbers(1000);
+ for (int i = 0; i < a.length; i++) {
+ System.out.println(a[i]);
+ }
+
+ // [2,3,5,7,11,13,17,19]
+ a = new ArrayUtil().getPrimes(20);
+ for (int i = 0; i < a.length; i++) {
+ System.out.println(a[i]);
+ }
+ }
+}
diff --git a/group01/1298552064/src/week02/litestruts/LoginAction.java b/group01/1298552064/src/week02/litestruts/LoginAction.java
new file mode 100644
index 0000000000..aec243dd1b
--- /dev/null
+++ b/group01/1298552064/src/week02/litestruts/LoginAction.java
@@ -0,0 +1,42 @@
+package week02.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ *
+ * @author liuxin
+ *
+ */
+public class LoginAction {
+ private String name;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute() {
+ if ("test".equals(name) && "1234".equals(password)) {
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getMessage() {
+ return this.message;
+ }
+}
diff --git a/group01/1298552064/src/week02/litestruts/Struts.java b/group01/1298552064/src/week02/litestruts/Struts.java
new file mode 100644
index 0000000000..3cef26c396
--- /dev/null
+++ b/group01/1298552064/src/week02/litestruts/Struts.java
@@ -0,0 +1,106 @@
+package week02.litestruts;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+public class Struts {
+
+ public static View runAction(String actionName, Map parameters) {
+
+ /*
+ *
+ * 0. 读取配置文件struts.xml
+ *
+ * 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" ,
+ * "password"="1234") , 那就应该调用 setName和setPassword方法
+ *
+ * 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+ *
+ * 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如
+ * {"message": "登录成功"} , 放到View对象的parameters
+ *
+ * 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ * 放到View对象的jsp字段中。
+ *
+ */
+
+ try {
+
+ // 0. 读取配置文件struts.xml
+ SAXReader reader = new SAXReader();
+ InputStream in = Struts.class.getResourceAsStream("struts.xml");
+ Document document = reader.read(in);
+ Element root = document.getRootElement();
+
+ // 与actionName匹配的Element
+ Element actionElement = null;
+ String className = null;
+
+ for (Iterator iterator = root.elementIterator("action"); iterator.hasNext();) {
+ Element e = iterator.next();
+ if (e.attributeValue("name").equals(actionName)) {
+ actionElement = e;
+ className = e.attributeValue("class");
+ break;
+ }
+ }
+
+ Class> clazz = Class.forName(className);
+ Object action = clazz.newInstance();
+
+ // 1. 反射设置属性
+ if (parameters != null) {
+ for (Map.Entry entry : parameters.entrySet()) {
+ String fieldName = entry.getKey();
+ String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+ Class> fieldType = clazz.getDeclaredField(fieldName).getType();
+ Method method = clazz.getDeclaredMethod(methodName, fieldType);
+ method.invoke(action, entry.getValue());
+ }
+ }
+
+ // 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+ Method execute = clazz.getDeclaredMethod("execute");
+ String result = (String) execute.invoke(action);
+
+ // 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap
+ Method[] methods = clazz.getDeclaredMethods();
+ Map param = new HashMap();
+ for (Method method : methods) {
+ String methodName = method.getName();
+ if (method.getName().startsWith("get")) {
+ String fieldName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
+ Object fieldValue = method.invoke(action);
+ param.put(fieldName, fieldValue);
+ }
+ }
+
+ View view = new View();
+ view.setParameters(param);
+
+ // 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ // 放到View对象的jsp字段中。
+ for (Iterator iterator = actionElement.elementIterator("result"); iterator.hasNext();) {
+ Element resultElement = iterator.next();
+ if (resultElement.attributeValue("name").equals(result)) {
+ view.setJsp(resultElement.getText());
+ break;
+ }
+ }
+
+ return view;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/group01/1298552064/src/week02/litestruts/View.java b/group01/1298552064/src/week02/litestruts/View.java
new file mode 100644
index 0000000000..a286412f0e
--- /dev/null
+++ b/group01/1298552064/src/week02/litestruts/View.java
@@ -0,0 +1,26 @@
+package week02.litestruts;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/group01/1298552064/src/week02/litestruts/struts.xml b/group01/1298552064/src/week02/litestruts/struts.xml
new file mode 100644
index 0000000000..01398e9c3d
--- /dev/null
+++ b/group01/1298552064/src/week02/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/group01/1298552064/src/week02/test/ArrayUtilTest.java b/group01/1298552064/src/week02/test/ArrayUtilTest.java
new file mode 100644
index 0000000000..e796b5f845
--- /dev/null
+++ b/group01/1298552064/src/week02/test/ArrayUtilTest.java
@@ -0,0 +1,75 @@
+package week02.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import week02.array.ArrayUtil;
+
+public class ArrayUtilTest {
+
+ @Test
+ public void testReverseArray() {
+ int[] a = new int[] { 7, 9, 30, 3 };
+ int[] b = new int[] { 7, 9, 30, 3, 4 };
+
+ ArrayUtil.reverseArray(a);
+ ArrayUtil.reverseArray(b);
+
+ Assert.assertArrayEquals(new int[] { 3, 30, 9, 7 }, a);
+ Assert.assertArrayEquals(new int[] { 4, 3, 30, 9, 7 }, b);
+ }
+
+ @Test
+ public void testRemoveZero() {
+ int[] oldArr = new int[] { 1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 0, 5 };
+ int[] newArray = ArrayUtil.removeZero(oldArr);
+ Assert.assertArrayEquals(new int[] { 1, 3, 4, 5, 6, 6, 5, 4, 7, 6, 7, 5 }, newArray);
+ }
+
+ @Test
+ public void testMerge() {
+ int[] a1 = new int[] { 3, 5, 7, 8 };
+ int[] a2 = new int[] { 4, 5, 6, 6, 7, 7 };
+ int[] a3 = ArrayUtil.merge(a1, a2);
+ Assert.assertArrayEquals(new int[] { 3, 4, 5, 6, 7, 8 }, a3);
+ }
+
+ @Test
+ public void testGrow() {
+ int[] oldArray = new int[] { 2, 3, 6 };
+ int size = 3;
+ int[] newArray = ArrayUtil.grow(oldArray, size);
+ Assert.assertArrayEquals(new int[] { 2, 3, 6, 0, 0, 0 }, newArray);
+ }
+
+ @Test
+ public void testFibonacci() {
+ int max = 15;
+ int max2 = 1;
+ int[] newArray = ArrayUtil.fibonacci(max);
+ int[] newArray2 = ArrayUtil.fibonacci(max2);
+ Assert.assertArrayEquals(new int[] { 1, 1, 2, 3, 5, 8, 13 }, newArray);
+ Assert.assertArrayEquals(new int[] {}, newArray2);
+ }
+
+ @Test
+ public void testGetPrimes() {
+ int[] newArray = ArrayUtil.getPrimes(23);
+ Assert.assertArrayEquals(new int[] { 2, 3, 5, 7, 11, 13, 17, 19 }, newArray);
+ }
+
+ @Test
+ public void testGetPerfectNumbers() {
+ int[] newArray = ArrayUtil.getPerfectNumbers(1000);
+ Assert.assertArrayEquals(new int[] { 6, 28, 496 }, newArray);
+ }
+
+ @Test
+ public void testJoin() {
+ int[] array = new int[] { 3, 8, 9 };
+ String seperator = "-";
+ String result = ArrayUtil.join(array, seperator);
+ Assert.assertEquals("3-8-9", result);
+ }
+
+}
diff --git a/group01/1298552064/src/week02/test/StrutsTest.java b/group01/1298552064/src/week02/test/StrutsTest.java
new file mode 100644
index 0000000000..3eb6d01fd0
--- /dev/null
+++ b/group01/1298552064/src/week02/test/StrutsTest.java
@@ -0,0 +1,41 @@
+package week02.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import week02.litestruts.Struts;
+import week02.litestruts.View;
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name", "test");
+ params.put("password", "1234");
+
+ View view = Struts.runAction(actionName, params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name", "test");
+ params.put("password", "123456"); // 密码和预设的不一致
+
+ View view = Struts.runAction(actionName, params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/group01/1298552064/src/week03/basic/MyLinkedList.java b/group01/1298552064/src/week03/basic/MyLinkedList.java
new file mode 100644
index 0000000000..14cec304f4
--- /dev/null
+++ b/group01/1298552064/src/week03/basic/MyLinkedList.java
@@ -0,0 +1,366 @@
+package week03.basic;
+
+import java.util.Objects;
+
+import week01.basic.Iterator;
+import week01.basic.List;
+
+public class MyLinkedList implements List {
+
+ private Node head;
+ private int size;
+
+ /**************************************** 第一次作业 ***************************************/
+ public void add(Object o) {
+ // 空链表
+ if (head == null) {
+ head = new Node();
+ head.data = o;
+ head.next = null;
+ } else {
+ Node p = head;
+ while (p.next != null) {
+ p = p.next;
+ }
+
+ Node target = new Node();
+ target.data = o;
+ target.next = null;
+ p.next = target;
+ }
+ size++;
+ }
+
+ public void add(int index, Object o) {
+ // index 是否合法
+ checkPositionIndex(index);
+ if (head == null) {
+ head = new Node();
+ head.data = o;
+ head.next = null;
+ } else {
+ if (index == 0) {
+ addFirst(o);
+ } else if (index == size) {
+ addLast(o);
+ } else {
+ Node p = new Node();
+ Node p1 = head;
+ for (int i = 0; i < index - 1; i++) {
+ p1 = p1.next;
+ }
+ p.data = o;
+ p.next = p1.next;
+ p1.next = p;
+
+ size++;
+ }
+ }
+ }
+
+ public Object get(int index) {
+ checkElementIndex(index);
+ Node p = head;
+ for (int i = 0; i < index; i++) {
+ p = p.next;
+ }
+ return p.data;
+ }
+
+ public Object remove(int index) {
+ checkElementRemove();
+ checkElementIndex(index);
+
+ Object removeObject = null;
+ if (index == 0) {
+ removeObject = removeFirst();
+ } else if (index == (size - 1)) {
+ removeObject = removeLast();
+ } else {
+ Node p = head;
+ for (int i = 1; i < index; i++) {
+ p = p.next;
+ }
+ removeObject = p.next.data;
+ p.next = p.next.next;
+ size--;
+ }
+ return removeObject;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public void addFirst(Object o) {
+ if (head == null) {
+ head = new Node();
+ head.data = o;
+ head.next = null;
+ } else {
+ Node p = new Node();
+ p.data = o;
+ p.next = head;
+ head = p;
+ }
+ size++;
+ }
+
+ public void addLast(Object o) {
+ add(o);
+ }
+
+ public Object removeFirst() {
+ checkElementRemove();
+ Object removeObject = head.data;
+ head = head.next;
+ size--;
+ return removeObject;
+ }
+
+ public Object removeLast() {
+ checkElementRemove();
+
+ Object removeObject = null;
+
+ if (size == 1) {
+ removeObject = head.data;
+ head = head.next;
+ } else {
+ Node p = head;
+ for (int i = 0; i < size; i++) {
+ if (p.next.next == null) {
+ removeObject = p.next.data;
+ p.next = null;
+ break;
+ } else {
+ p = p.next;
+ }
+ }
+ }
+ size--;
+ return removeObject;
+ }
+
+ private boolean isEmpty() {
+ return size == 0;
+ }
+
+ private void checkElementRemove() {
+ if (isEmpty()) {
+ throw new NullPointerException("The list is empty.");
+ }
+ }
+
+ private void checkElementIndex(int index) {
+ if (!isElementIndex(index)) {
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+ }
+
+ private boolean isElementIndex(int index) {
+ return index >= 0 && index < size;
+ }
+
+ private void checkPositionIndex(int index) {
+ if (!isPositionIndex(index)) {
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+ }
+
+ private boolean isPositionIndex(int index) {
+ return index >= 0 && index <= size;
+ }
+
+ public Iterator iterator() {
+ return new MyLinkedListIterator(this);
+ }
+
+ private class MyLinkedListIterator implements Iterator {
+ private MyLinkedList list = null;
+ private int position = 0;
+
+ private MyLinkedListIterator(MyLinkedList list) {
+ this.list = list;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if ((position + 1) > size()) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public Object next() {
+ return list.get(position++);
+ }
+ }
+
+ private static class Node {
+ Object data;
+ Node next;
+ }
+
+ /****************************************
+ * 第三次作业 ***************************************
+ *
+ *
+ * /** 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse() {
+ Node p = this.head.next;
+ head.next = null;
+ while (p != null) {
+ addFirst(p.data);
+ size--;
+ p = p.next;
+ }
+ }
+
+ /**
+ * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10
+ * ,删除以后的值为7,8,10
+ *
+ */
+ public void removeFirstHalf() {
+ int removeSize = size / 2;
+ for (int i = 0; i < removeSize; i++) {
+ head = head.next;
+ }
+ }
+
+ /**
+ * 从第i个元素开始, 删除length 个元素 , 注意i从0开始
+ *
+ * @param i
+ * @param length
+ */
+ public void remove(int i, int length) {
+ for (int index = 0; index < length; index++) {
+ remove(i);
+ }
+ }
+
+ /**
+ * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 =
+ * 11->101->201->301->401->501->601->701 listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ *
+ * @param list
+ */
+ public int[] getElements(MyLinkedList list) {
+ int[] array = new int[list.size];
+ int i = 0;
+ for (Node head = list.head; head != null; head = head.next) {
+ array[i++] = (int) this.get((int) head.data);
+ }
+ return array;
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素
+ *
+ * @param list
+ */
+
+ public void subtract(MyLinkedList list) {
+ for (Iterator iterator = list.iterator(); iterator.hasNext();) {
+ Object data = iterator.next();
+ Node p = head;
+ int index = 0;
+ while (p != null) {
+ if (Objects.equals(p.data, data)) {
+ this.remove(index);
+ break;
+ } else {
+ p = p.next;
+ index++;
+ }
+ }
+ }
+ }
+
+ /**
+ * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
+ */
+ public void removeDuplicateValues() {
+ if (size == 0 || size == 1) {
+ return;
+ }
+
+ Node p1 = head;
+ Node p2 = head.next;
+
+ while (p1 != null && p2 != null) {
+ if (Objects.equals(p1.data, p2.data)) {
+ p2 = p2.next;
+ p1.next = p2;
+ size--;
+ } else {
+ p1 = p2;
+ p2 = p2.next;
+ }
+ }
+
+ }
+
+ /**
+ * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
+ *
+ * @param min
+ * @param max
+ */
+ public void removeRange(int min, int max) {
+ Node p1 = head;
+ Node p2 = head;
+ while ((int) p2.data < max) {
+ if ((int) p1.next.data <= min) {
+ p1 = p1.next;
+ }
+
+ if ((int) p2.data < max) {
+ p2 = p2.next;
+ }
+ }
+ p1.next = p2;
+
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ *
+ * @param list
+ */
+ public MyLinkedList intersection(MyLinkedList list) {
+ MyLinkedList rsList = new MyLinkedList();
+ Node p1 = this.head, p2 = list.head;
+ while (p1 != null && p2 != null) {
+ if (Objects.equals(p1.data, p2.data)) {
+ rsList.add(p1.data);
+ p1 = p1.next;
+ p2 = p2.next;
+ } else if ((int) p1.data > (int) p2.data) {
+ p2 = p2.next;
+ } else {
+ p1 = p1.next;
+ }
+ }
+ return rsList;
+ }
+
+ @Override
+ public String toString() {
+ String elementStr = "";
+ Node p = head;
+ while (p != null) {
+ elementStr += p.data + ",";
+ p = p.next;
+ }
+
+ return "MyLinkedList: { size=" + size + ", elementData=" + "["
+ + elementStr.substring(0, elementStr.length() - 1) + "]" + " }";
+ }
+}
diff --git a/group01/1298552064/src/week03/download/DownloadThread.java b/group01/1298552064/src/week03/download/DownloadThread.java
new file mode 100644
index 0000000000..2e25c5aa10
--- /dev/null
+++ b/group01/1298552064/src/week03/download/DownloadThread.java
@@ -0,0 +1,43 @@
+package week03.download;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import week03.download.api.Connection;
+
+public class DownloadThread extends Thread {
+
+ Connection conn;
+ int startPos;
+ int endPos;
+ String targetPath;
+
+ public DownloadThread(Connection conn, int startPos, int endPos) {
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+
+ public DownloadThread(Connection conn, int startPos, int endPos, String targetPath) {
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ this.targetPath = targetPath;
+ }
+
+ public void run() {
+ try {
+ System.out.println("线程" + this.getName() + "开始下载. startPos:" + startPos + "; endPos:" + endPos);
+ byte[] rs = conn.read(startPos, endPos);
+ RandomAccessFile raf = new RandomAccessFile(targetPath, "rw");
+ raf.seek(startPos);
+ raf.write(rs, 0, rs.length);
+ raf.close();
+ System.out.println("线程" + this.getName() + "下载完成.");
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+}
diff --git a/group01/1298552064/src/week03/download/FileDownloader.java b/group01/1298552064/src/week03/download/FileDownloader.java
new file mode 100644
index 0000000000..b4dba9e2a0
--- /dev/null
+++ b/group01/1298552064/src/week03/download/FileDownloader.java
@@ -0,0 +1,92 @@
+package week03.download;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import week03.download.api.Connection;
+import week03.download.api.ConnectionException;
+import week03.download.api.ConnectionManager;
+import week03.download.api.DownloadListener;
+
+public class FileDownloader {
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+ private final static String BASE_PATH = "E:\\";
+ private final static int THREAD_COUNT = 3;
+
+ public FileDownloader(String _url) {
+ this.url = _url;
+ }
+
+ public void setConnectionManager(ConnectionManager ucm) {
+ this.cm = ucm;
+ }
+
+ public void setListener(DownloadListener listener) {
+ this.listener = listener;
+ }
+
+ public DownloadListener getListener() {
+ return this.listener;
+ }
+
+ public void execute() {
+ // 在这里实现你的代码, 注意: 需要用多线程实现下载
+ // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+ // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos,
+ // endPos来指定)
+ // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
+ // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
+ // 具体的实现思路:
+ // 1. 需要调用ConnectionManager的open方法打开连接,
+ // 然后通过Connection.getContentLength方法获得文件的长度
+ // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
+ // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
+ // 3. 把byte数组写入到文件中
+ // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+ Connection conn = null;
+
+ int startPos = 0, endPos = 0;
+ try {
+ conn = cm.open(this.url);
+ int length = conn.getContentLength();
+ String targetPath = BASE_PATH + "targetfile." + url.substring(url.lastIndexOf(".") + 1);
+ List list = new ArrayList<>();
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ conn = cm.open(this.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/group01/1298552064/src/week03/download/api/Connection.java b/group01/1298552064/src/week03/download/api/Connection.java
new file mode 100644
index 0000000000..bb19987547
--- /dev/null
+++ b/group01/1298552064/src/week03/download/api/Connection.java
@@ -0,0 +1,24 @@
+package week03.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+ /**
+ * 给定开始和结束位置, 读取数据, 返回值是字节数组
+ * @param startPos 开始位置, 从0开始
+ * @param endPos 结束位置
+ * @return
+ */
+ public byte[] read(int startPos,int endPos) throws IOException;
+ /**
+ * 得到数据内容的长度
+ * @return
+ */
+ public int getContentLength();
+
+ /**
+ * 关闭连接
+ * @throws IOException
+ */
+ public void close();
+}
diff --git a/group01/1298552064/src/week03/download/api/ConnectionException.java b/group01/1298552064/src/week03/download/api/ConnectionException.java
new file mode 100644
index 0000000000..72bb7fdbfe
--- /dev/null
+++ b/group01/1298552064/src/week03/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package week03.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/group01/1298552064/src/week03/download/api/ConnectionManager.java b/group01/1298552064/src/week03/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..45c3b5d361
--- /dev/null
+++ b/group01/1298552064/src/week03/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package week03.download.api;
+
+public interface ConnectionManager {
+ /**
+ * 给定一个url , 打开一个连接
+ * @param url
+ * @return
+ */
+ public Connection open(String url) throws ConnectionException;
+}
diff --git a/group01/1298552064/src/week03/download/api/DownloadListener.java b/group01/1298552064/src/week03/download/api/DownloadListener.java
new file mode 100644
index 0000000000..1e625cdab7
--- /dev/null
+++ b/group01/1298552064/src/week03/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package week03.download.api;
+
+public interface DownloadListener {
+ public void notifyFinished();
+}
diff --git a/group01/1298552064/src/week03/download/impl/ConnectionImpl.java b/group01/1298552064/src/week03/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..e26760124f
--- /dev/null
+++ b/group01/1298552064/src/week03/download/impl/ConnectionImpl.java
@@ -0,0 +1,59 @@
+package week03.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import week03.download.api.Connection;
+
+public class ConnectionImpl implements Connection {
+ private String url;
+ private HttpURLConnection connection;
+
+ public ConnectionImpl(String url) {
+ this.url = url;
+ initConnection();
+ }
+
+ /**
+ * 获取HttpURLConnection
+ */
+ private void initConnection() {
+ try {
+ URL targetUrl = new URL(url);
+ connection = (HttpURLConnection) targetUrl.openConnection();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public byte[] read(int startPos, int endPos) throws IOException {
+
+ connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+ InputStream in = connection.getInputStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int len = 0;
+ byte[] rs = new byte[1024];
+ while ((len = in.read(rs)) != -1) {
+ out.write(rs, 0, len);
+ }
+ out.close();
+ in.close();
+ return out.toByteArray();
+
+ }
+
+ @Override
+ public int getContentLength() {
+ return connection.getContentLength();
+ }
+
+ @Override
+ public void close() {
+ connection.disconnect();
+ }
+}
diff --git a/group01/1298552064/src/week03/download/impl/ConnectionManagerImpl.java b/group01/1298552064/src/week03/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..2849d3a03b
--- /dev/null
+++ b/group01/1298552064/src/week03/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,13 @@
+package week03.download.impl;
+
+import week03.download.api.Connection;
+import week03.download.api.ConnectionException;
+import week03.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+ @Override
+ public Connection open(String url) throws ConnectionException {
+ return new ConnectionImpl(url);
+ }
+}
diff --git a/group01/1298552064/src/week03/test/FileDownloaderTest.java b/group01/1298552064/src/week03/test/FileDownloaderTest.java
new file mode 100644
index 0000000000..ab0dd1906b
--- /dev/null
+++ b/group01/1298552064/src/week03/test/FileDownloaderTest.java
@@ -0,0 +1,55 @@
+package week03.test;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import week03.download.FileDownloader;
+import week03.download.api.ConnectionManager;
+import week03.download.api.DownloadListener;
+import week03.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+ boolean downloadFinished = false;
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testDownload() {
+ String url = "http://127.0.0.1:8080/files/eclipse-jee-neon-2-win32-x86_64.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 (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("下载完成!");
+
+ }
+
+}
diff --git a/group01/1298552064/src/week03/test/MyLinkedListTest.java b/group01/1298552064/src/week03/test/MyLinkedListTest.java
new file mode 100644
index 0000000000..26e5c75c48
--- /dev/null
+++ b/group01/1298552064/src/week03/test/MyLinkedListTest.java
@@ -0,0 +1,179 @@
+package week03.test;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import week03.basic.MyLinkedList;
+
+public class MyLinkedListTest {
+
+ MyLinkedList list = null;
+ MyLinkedList list1 = null;
+
+ @Before
+ public void setUp() {
+ list = new MyLinkedList();
+ list1 = new MyLinkedList();
+ }
+
+ @After
+ public void tearDown() {
+ list = null;
+ list1 = null;
+ }
+
+ @Test
+ public void testReverse() {
+ list.add(3);
+ list.add(7);
+ list.add(10);
+
+ list.reverse();
+
+ int[] rs = new int[]{10,7,3};
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list.get(i));
+ }
+ }
+
+ @Test
+ public void testRemoveFirstHalf() {
+
+ list.add(2);
+ list.add(5);
+ list.add(7);
+ list.add(8);
+ list.removeFirstHalf();
+ int []rs = new int[]{7,8};
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list.get(i));
+ }
+
+ list1.add(2);
+ list1.add(5);
+ list1.add(7);
+ list1.add(8);
+ list1.add(10);
+ list1.removeFirstHalf();
+ rs = new int[]{7,8,10};
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list1.get(i));
+ }
+
+ }
+
+ @Test
+ public void testRemove() {
+ list.add(2);
+ list.add(5);
+ list.add(7);
+ list.add(8);
+
+ list.remove(1, 2);
+ int []rs = new int[]{2,8};
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list.get(i));
+ }
+
+ }
+
+ @Test
+ public void testGetElements() {
+ list.add(11);
+ list.add(101);
+ list.add(201);
+ list.add(301);
+ list.add(401);
+ list.add(501);
+ list.add(601);
+ list.add(701);
+
+ list1.add(1);
+ list1.add(3);
+ list1.add(4);
+ list1.add(6);
+
+ int[] actualRs = new int[]{101,301,401,601};
+ int[] rs = list.getElements(list1);
+ Assert.assertArrayEquals(actualRs, rs);
+ }
+
+ @Test
+ public void testSubtract() {
+
+ list.add(2);
+ list.add(3);
+ list.add(5);
+ list.add(7);
+ list.add(9);
+
+ list1.add(3);
+ list1.add(5);
+
+ list.subtract(list1);
+
+ int[] rs = new int[] { 2, 7, 9 };
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list.get(i));
+ }
+ }
+
+ @Test
+ public void testRemoveDuplicateValues() {
+ list.add(2);
+ list.add(3);
+ list.add(5);
+ list.add(5);
+ list.add(6);
+ list.add(6);
+ list.add(8);
+
+ list.removeDuplicateValues();
+
+ int[] rs = new int[] { 2, 3, 5, 6, 8 };
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list.get(i));
+ }
+ }
+
+ @Test
+ public void testRemoveRange() {
+ list.add(2);
+ list.add(3);
+ list.add(5);
+ list.add(7);
+ list.add(9);
+
+ list.removeRange(3, 8);
+
+ int[] rs = new int[] { 2, 3, 9 };
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], list.get(i));
+ }
+ }
+
+ @Test
+ public void testIntersection() {
+ list.add(2);
+ list.add(3);
+ list.add(5);
+ list.add(7);
+ list.add(8);
+ list.add(9);
+ list.add(13);
+
+ list1.add(3);
+ list1.add(7);
+ list1.add(9);
+ list1.add(14);
+
+ MyLinkedList rsList = list.intersection(list1);
+ int[] rs = new int[] { 3, 7, 9 };
+ for (int i = 0; i < rs.length; i++) {
+ Assert.assertEquals(rs[i], rsList.get(i));
+ }
+ }
+
+}
diff --git a/group01/1664823950/src/com/coderising/array/ArrayUtil.java b/group01/1664823950/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..afb557277f
--- /dev/null
+++ b/group01/1664823950/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,209 @@
+package com.coderising.array;
+import java.util.*;
+
+import com.sun.org.apache.bcel.internal.generic.NEWARRAY;
+
+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[] a = origin;
+ for (int i = 0; i < a.length; i++)
+ {
+ origin[i] = a[a.length-i];
+ }
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public int[] removeZero(int[] oldArray)
+ {
+ ArrayList a= new ArrayList();
+
+ for (int i : oldArray)
+ {
+ if (i != 0)
+ {
+ a.add(i);
+ }
+ }
+
+ int[] newArray = new int[a.size()];
+ for (int i = 0; i < a.size(); i++)
+ {
+ newArray[i] = a.get(i);
+ }
+ 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)
+ {
+ for (int i = 0; i < array1.length; i++)
+ {
+ for (int j = 0; j < array2.length; j++)
+ {
+ if(array1[i] == array2[j])
+ {
+ array2[j] = 0;
+ }
+ }
+ }
+
+ removeZero(array2);
+
+ int[] array3 = new int[array1.length + array2.length];
+
+ for (int i = 0; i < array1.length; i++)
+ {
+ array3[i] = array1[i];
+ }
+
+ for (int i = 0; i < array2.length; i++)
+ {
+ array3[array1.length + i] = array2[i];
+ }
+
+ Arrays.sort(array3);
+ 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)
+ {
+ return new int[oldArray.length + size];
+ }
+
+ /**
+ * 斐波那契数列为: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 top = 1;
+ int sec = 1;
+ ArrayList tem = new ArrayList();
+ while (top < max)
+ {
+ tem.add(top);
+ int a = top;
+ top += sec;
+ sec = a;
+ }
+
+
+ return toArray(tem);
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public int[] getPrimes(int max)
+ {
+ ArrayList tem = new ArrayList();
+ for (int i = 0; i < max; i++)
+ {
+ if (isPrimes(i))
+ {
+ tem.add(i);
+ }
+ }
+
+ return toArray(tem);
+ }
+
+ private boolean isPrimes(int i)
+ {
+ return true;
+ }
+
+ private int[] toArray(ArrayList tem)
+ {
+ int[] newArr = new int[tem.size()];
+ for (int i = 0; i < newArr.length; i++)
+ {
+ newArr[i] = tem.get(i);
+ }
+ return newArr;
+ }
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public int[] getPerfectNumbers(int max)
+ {
+ ArrayList tem = new ArrayList();
+ for (int i = 0; i < max; i++)
+ {
+ if (isPerfectNumbers(i))
+ {
+ tem.add(i);
+ }
+ }
+
+ return toArray(tem);
+ }
+
+
+ private boolean isPerfectNumbers(int i)
+ {
+ return true;
+ }
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public String join(int[] array, String seperator)
+ {
+ String newStr = "";
+ for (int i = 0; i < array.length; i++)
+ {
+ if(i == array.length-1)
+ {
+ seperator = "";
+ }
+ newStr += array[i] + seperator;
+ }
+ return newStr;
+ }
+
+}
diff --git a/group01/1664823950/src/com/coderising/litestruts/LoginAction.java b/group01/1664823950/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..1005f35a29
--- /dev/null
+++ b/group01/1664823950/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/group01/1664823950/src/com/coderising/litestruts/Struts.java b/group01/1664823950/src/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..44cc35bf01
--- /dev/null
+++ b/group01/1664823950/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/group01/1664823950/src/com/coderising/litestruts/StrutsTest.java b/group01/1664823950/src/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..a44c1878ac
--- /dev/null
+++ b/group01/1664823950/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/group01/1664823950/src/com/coderising/litestruts/View.java b/group01/1664823950/src/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..0194c681f6
--- /dev/null
+++ b/group01/1664823950/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/group01/1664823950/src/com/coderising/litestruts/struts.xml b/group01/1664823950/src/com/coderising/litestruts/struts.xml
new file mode 100644
index 0000000000..99063bcb0c
--- /dev/null
+++ b/group01/1664823950/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/group01/1814014897/zhouhui/src/.project b/group01/1814014897/zhouhui/src/.project
new file mode 100644
index 0000000000..f7d6de6781
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/.project
@@ -0,0 +1,11 @@
+
+
+ src
+
+
+
+
+
+
+
+
diff --git a/group01/1814014897/zhouhui/src/week01/datastructure/ArrayList.java b/group01/1814014897/zhouhui/src/week01/datastructure/ArrayList.java
new file mode 100644
index 0000000000..96f1b23737
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/ArrayList.java
@@ -0,0 +1,75 @@
+package week01.datastructure;
+
+import java.util.Arrays;
+
+public class ArrayList implements List {
+
+ private int size = 0;
+
+ private Object[] elementData = new Object[100];
+
+ public void add(Object o){
+ ensureCapacity(size + 1); //size increase,in order to have enough capacity.
+ elementData[size++] = o; //similar to: elementData[size]=o; size++;
+ }
+
+ private void ensureCapacity(int minCapacity){
+ if(minCapacity > elementData.length){
+ grow(minCapacity);
+ }
+ }
+
+ private void grow(int minCapacity){
+ int oldCapacity = elementData.length;
+ int newCapacity = oldCapacity + ( oldCapacity >> 1 );
+ if(newCapacity < minCapacity){
+ newCapacity = minCapacity;
+ }
+ elementData = Arrays.copyOf(elementData, newCapacity);
+
+ }
+
+ public void add(int index, Object o){
+ if(index < 0 || index > size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size);
+ ensureCapacity(size+1);
+ System.arraycopy(elementData, index, elementData, index + 1, size - index);
+ elementData[index] = o;
+ size++;
+ }
+
+ public Object get(int index){
+ if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size);
+ return elementData[index];
+ }
+
+ public Object remove(int index){
+ if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size);
+ Object data_index = elementData[index];
+ System.arraycopy(elementData, index + 1, elementData, index, size - index - 1);
+ elementData[size - 1] = null;
+ size--;
+ return data_index;
+ }
+
+ public int size(){
+ return size;
+ }
+
+ public Iterator iterator(){
+ return new ArrayListIterator();
+ }
+
+ private class ArrayListIterator implements Iterator{
+
+ private int pos = 0;
+
+ public boolean hasNext() {
+ return pos < size;
+ }
+
+ public Object next() {
+ return elementData[pos++];
+ }
+ }
+
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructure/BinaryTreeNode.java b/group01/1814014897/zhouhui/src/week01/datastructure/BinaryTreeNode.java
new file mode 100644
index 0000000000..f546122f4c
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/BinaryTreeNode.java
@@ -0,0 +1,56 @@
+package week01.datastructure;
+
+public class BinaryTreeNode{
+
+ private Object data;
+ private BinaryTreeNode left;
+ private BinaryTreeNode right;
+
+ public BinaryTreeNode(Object data){
+ this.data = data;
+ left = null;
+ right = null;
+ }
+
+ public Object getData() {
+ return data;
+ }
+ public void setData(Object data) {
+ this.data = data;
+ }
+ public BinaryTreeNode getLeft() {
+ return left;
+ }
+ public void setLeft(BinaryTreeNode left) {
+ this.left = left;
+ }
+ public BinaryTreeNode getRight() {
+ return right;
+ }
+ public void setRight(BinaryTreeNode right) {
+ this.right = right;
+ }
+
+ public BinaryTreeNode insert(Object o){
+ if((Integer)o < (Integer)this.data)
+ {
+ if(this.left == null){
+ BinaryTreeNode node = new BinaryTreeNode(o);
+ this.setLeft(node);
+ return node;
+ }else{
+ return this.left.insert(o);
+ }
+ }else{
+ if(this.right == null){
+ BinaryTreeNode node = new BinaryTreeNode(o);
+ this.setRight(node);
+ return node;
+ }else{
+ return this.right.insert(o);
+ }
+ }
+ }
+ }
+
+
diff --git a/group01/1814014897/zhouhui/src/week01/datastructure/Iterator.java b/group01/1814014897/zhouhui/src/week01/datastructure/Iterator.java
new file mode 100644
index 0000000000..bf59b406cc
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/Iterator.java
@@ -0,0 +1,7 @@
+package week01.datastructure;
+
+public interface Iterator {
+ public boolean hasNext();
+ public Object next();
+
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructure/LinkedList.java b/group01/1814014897/zhouhui/src/week01/datastructure/LinkedList.java
new file mode 100644
index 0000000000..15ef81ed3e
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/LinkedList.java
@@ -0,0 +1,113 @@
+package week01.datastructure;
+
+public class LinkedList implements List {
+
+ private Node head;
+ private int size = 0;
+
+ public void add(Object o){
+ if(head == null){
+ head = new Node(o);
+ }else{
+ Node pos = head;
+ while(pos.next != null){
+ pos = pos.next;
+ }
+ pos.next = new Node(o);
+ }
+ size++;
+ }
+
+ public void add(int index , Object o){
+ if(index < 0 || index >size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size);
+ if(index == 0) {
+ Node node = new Node(o);
+ node.next = head;
+ head = node;
+ }
+ else{
+ Node pos = head;
+ for(int i = 0;i < index-1;i++){
+ pos = pos.next;
+ }
+ Node node = new Node(o);
+ node.next = pos.next;
+ pos.next = node;
+ }
+ size++;
+ }
+
+ public Object get(int index){
+ if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size);
+ Node pos = head;
+ for(int i = 0;i < index;i++){
+ pos = pos.next;
+ }
+ return pos.data;
+ }
+
+ public Object remove(int index){
+ if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size:"+size);
+ Node element = head;
+ if(index == 0){
+ head = head.next;
+ }else{
+ Node pos = head;
+ for(int i = 0;i < index - 1;i++){
+ pos = pos.next;
+ }
+ element = pos.next;
+ pos.next = pos.next.next;
+ }
+ size--;
+ return element.data;
+ }
+
+ public int size(){
+ return size;
+ }
+
+ public void addFirst(Object o){
+ add(0,o);
+ }
+ public void addLast(Object o){
+ add(size,o);
+ }
+ public Object removeFirst(){
+ return remove(0);
+ }
+ public Object removeLast(){
+ return remove(size-1);
+ }
+ public Iterator iterator(){
+ return new LinkedListIterator();
+ }
+
+ class LinkedListIterator implements Iterator{
+
+ private Node node = head;
+ private int pos = 0;
+ @Override
+ public boolean hasNext() {
+ return pos < size;
+ }
+
+ @Override
+ public Object next() {
+ pos++;
+ if(pos != 1){
+ node = node.next;
+ }
+ return node.data;
+ }
+ }
+
+ private static class Node{
+ Object data;
+ Node next;
+ public Node(Object data){
+ this.data = data;
+ next = null;
+ }
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructure/List.java b/group01/1814014897/zhouhui/src/week01/datastructure/List.java
new file mode 100644
index 0000000000..0f54344c2c
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/List.java
@@ -0,0 +1,9 @@
+package week01.datastructure;
+
+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/group01/1814014897/zhouhui/src/week01/datastructure/Queue.java b/group01/1814014897/zhouhui/src/week01/datastructure/Queue.java
new file mode 100644
index 0000000000..48fd480698
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/Queue.java
@@ -0,0 +1,25 @@
+package week01.datastructure;
+
+public class Queue {
+
+ private LinkedList linkedList = new LinkedList();
+ private int size = 0;
+
+ public void enQueue(Object o){
+ linkedList.add(o);
+ size++;
+ }
+
+ public Object deQueue(){
+ size--;
+ return linkedList.removeFirst();
+ }
+
+ public boolean isEmpty(){
+ return linkedList.size() == 0;
+ }
+
+ public int size(){
+ return size;
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructure/Stack.java b/group01/1814014897/zhouhui/src/week01/datastructure/Stack.java
new file mode 100644
index 0000000000..5d8c66c087
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructure/Stack.java
@@ -0,0 +1,25 @@
+package week01.datastructure;
+
+public class Stack {
+ private ArrayList elementData = new ArrayList();
+ private int size = 0;
+
+ public void push(Object o){
+ elementData.add(o);
+ size++;
+ }
+
+ public Object pop(){
+ return elementData.remove(--size);
+ }
+
+ public Object peek(){
+ return elementData.get(size - 1);
+ }
+ public boolean isEmpty(){
+ return elementData.size() == 0;
+ }
+ public int size(){
+ return elementData.size();
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructuretest/AllTest.java b/group01/1814014897/zhouhui/src/week01/datastructuretest/AllTest.java
new file mode 100644
index 0000000000..bfb1259a20
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructuretest/AllTest.java
@@ -0,0 +1,18 @@
+package week01.datastructuretest;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ ArrayListTest.class,
+ BinaryTreeNodeTest.class,
+ LinkedListTest.class,
+ QueueTest.class,
+ StackTest.class
+})
+
+public class AllTest {
+
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructuretest/ArrayListTest.java b/group01/1814014897/zhouhui/src/week01/datastructuretest/ArrayListTest.java
new file mode 100644
index 0000000000..75412b9b5b
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructuretest/ArrayListTest.java
@@ -0,0 +1,72 @@
+package week01.datastructuretest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import week01.datastructure.ArrayList;
+import week01.datastructure.Iterator;
+
+public class ArrayListTest {
+
+ private ArrayList arrayList = new ArrayList();
+
+ @Before
+ public void setUp() throws Exception {
+ for(int i = 0;i < 100 ; i++){
+ arrayList.add(i);
+ }
+ }
+
+ @Test
+ public void testAddObject() {
+ for(int i = 0;i < 100;i++){
+ Assert.assertEquals(arrayList.get(i), i);
+ }
+ }
+
+ @Test
+ public void testAddIntObject() {
+ arrayList.add(0,10);
+ arrayList.add(22, 44);
+ arrayList.add(40, 5);
+ arrayList.add(100,88);
+ Assert.assertEquals(arrayList.get(0), 10);
+ Assert.assertEquals(arrayList.get(22),44);
+ Assert.assertEquals(arrayList.get(40), 5);
+ Assert.assertEquals(arrayList.get(100), 88);
+ }
+
+ @Test
+ public void testGet() {
+ Assert.assertEquals(arrayList.get(0), 0);
+ Assert.assertEquals(arrayList.get(33), 33);
+ Assert.assertEquals(arrayList.get(77), 77);
+ Assert.assertEquals(arrayList.get(99), 99);
+ }
+
+ @Test
+ public void testRemove() {
+ Assert.assertEquals(arrayList.remove(0), 0);
+ Assert.assertEquals(arrayList.remove(0), 1);
+ Assert.assertEquals(arrayList.remove(97), 99);
+ Assert.assertEquals(arrayList.size(), 97);
+ }
+
+ @Test
+ public void testSize() {
+ Assert.assertEquals(arrayList.size(), 100);
+ arrayList.add(5,5);
+ Assert.assertEquals(arrayList.size(),101);
+ arrayList.remove(5);
+ Assert.assertEquals(arrayList.size(), 100);
+ }
+
+ @Test
+ public void testIterator() {
+ Iterator iterator = arrayList.iterator();
+ for(int i=0;iterator.hasNext();i++){
+ Assert.assertEquals(iterator.next(),i);
+ }
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructuretest/BinaryTreeNodeTest.java b/group01/1814014897/zhouhui/src/week01/datastructuretest/BinaryTreeNodeTest.java
new file mode 100644
index 0000000000..b7f6dccfe4
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructuretest/BinaryTreeNodeTest.java
@@ -0,0 +1,80 @@
+package week01.datastructuretest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import week01.datastructure.BinaryTreeNode;
+
+
+public class BinaryTreeNodeTest {
+
+ private BinaryTreeNode root = new BinaryTreeNode(5);
+
+ @Before
+ public void setUp() throws Exception {
+ root.insert(2);
+ root.insert(7);
+ root.insert(1);
+ root.insert(6);
+ }
+
+ @Test
+ public void testGetData() {
+ Assert.assertEquals(root.getData(), 5);
+ Assert.assertEquals(root.getLeft().getData(), 2);
+ Assert.assertEquals(root.getRight().getData(), 7);
+ Assert.assertEquals(root.getLeft().getLeft().getData(), 1);
+ Assert.assertEquals(root.getRight().getLeft().getData(), 6);
+ }
+
+ @Test
+ public void testSetData() {
+ root.setData(8);
+ Assert.assertEquals(root.getData(),8);
+ root.getLeft().setData(88);
+ Assert.assertEquals(root.getLeft().getData(),88);
+ root.getRight().setData(888);
+ Assert.assertEquals(root.getRight().getData(),888);
+ }
+
+ @Test
+ public void testGetLeft() {
+ BinaryTreeNode node_left = root.getLeft();
+ Assert.assertEquals(node_left.getData(), 2);
+ BinaryTreeNode node_left_left = root.getLeft().getLeft();
+ Assert.assertEquals(node_left_left.getData(), 1);
+ }
+
+ @Test
+ public void testSetLeft() {
+ BinaryTreeNode node = new BinaryTreeNode(100);
+ root.setLeft(node);
+ Assert.assertEquals(root.getLeft().getData(), 100);
+ }
+
+ @Test
+ public void testGetRight() {
+ BinaryTreeNode node_right = root.getRight();
+ Assert.assertEquals(node_right.getData(), 7);
+ root.insert(8);
+ BinaryTreeNode node_right_right = root.getRight().getRight();
+ Assert.assertEquals(node_right_right.getData(), 8);
+ }
+
+ @Test
+ public void testSetRight() {
+ BinaryTreeNode node = new BinaryTreeNode(100);
+ root.setRight(node);
+ Assert.assertEquals(root.getRight().getData(), 100);
+ }
+
+ @Test
+ public void testInsert() {
+ root.insert(4);
+ root.insert(8);
+ Assert.assertEquals(root.getLeft().getRight().getData(), 4);
+ Assert.assertEquals(root.getRight().getRight().getData(), 8);
+ }
+
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructuretest/LinkedListTest.java b/group01/1814014897/zhouhui/src/week01/datastructuretest/LinkedListTest.java
new file mode 100644
index 0000000000..945982e23e
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructuretest/LinkedListTest.java
@@ -0,0 +1,107 @@
+package week01.datastructuretest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import week01.datastructure.Iterator;
+import week01.datastructure.LinkedList;
+
+public class LinkedListTest {
+
+ private LinkedList linkedList = new LinkedList();
+
+ @Before
+ public void setUp() throws Exception {
+ for(int i=0;i<100;i++){
+ linkedList.add(i);
+ }
+ }
+
+ @Test
+ public void testAddObject() {
+ for(int i=0;i<200;i++){
+ linkedList.add(i);
+ }
+ for(int i=0;i<100;i++){
+ Assert.assertEquals(linkedList.get(i), i);
+ }
+ for(int i=100;i<300;i++){
+ Assert.assertEquals(linkedList.get(i), i-100);
+ }
+ }
+
+ @Test
+ public void testAddIntObject() {
+ linkedList.add(0, 10);
+ Assert.assertEquals(linkedList.get(0), 10);
+ linkedList.add(5,60);
+ Assert.assertEquals(linkedList.get(5), 60);
+ Assert.assertEquals(linkedList.get(101), 99);
+ }
+
+ @Test
+ public void testGet() {
+ for(int i =0;i<100;i++){
+ Assert.assertEquals(linkedList.get(i), i);
+ }
+ }
+
+ @Test
+ public void testRemove() {
+ Assert.assertEquals(linkedList.remove(0), 0);
+ Assert.assertEquals(linkedList.remove(0), 1);
+ Assert.assertEquals(linkedList.size(), 98);
+ linkedList.remove(97);
+ Assert.assertEquals(linkedList.get(96), 98);
+ }
+
+ @Test
+ public void testSize() {
+ linkedList.add(0);
+ Assert.assertEquals(linkedList.size(), 101);
+ linkedList.add(0, 10);
+ Assert.assertEquals(linkedList.size(), 102);
+ linkedList.remove(0);
+ Assert.assertEquals(linkedList.size(), 101);
+ }
+
+ @Test
+ public void testAddFirst() {
+ linkedList.addFirst(22);
+ Assert.assertEquals(linkedList.get(0), 22);
+ linkedList.addFirst(44);
+ Assert.assertEquals(linkedList.get(0), 44);
+ Assert.assertEquals(linkedList.size(), 102);
+ }
+
+ @Test
+ public void testAddLast() {
+ linkedList.addLast(22);
+ Assert.assertEquals(linkedList.get(100), 22);
+ linkedList.addLast(44);
+ Assert.assertEquals(linkedList.get(101), 44);
+ }
+
+ @Test
+ public void testRemoveFirst() {
+ Assert.assertEquals(linkedList.removeFirst(), 0);
+ Assert.assertEquals(linkedList.removeFirst(), 1);
+ Assert.assertEquals(linkedList.removeFirst(), 2);
+ }
+
+ @Test
+ public void testRemoveLast() {
+ Assert.assertEquals(linkedList.removeLast(),99 );
+ Assert.assertEquals(linkedList.removeLast(), 98);
+ }
+
+ @Test
+ public void testIterator() {
+ Iterator iterator = linkedList.iterator();
+ for(int i = 0;iterator.hasNext();i++){
+ Assert.assertEquals(iterator.next(), i);
+ }
+ }
+
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructuretest/QueueTest.java b/group01/1814014897/zhouhui/src/week01/datastructuretest/QueueTest.java
new file mode 100644
index 0000000000..03ffdc0024
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructuretest/QueueTest.java
@@ -0,0 +1,56 @@
+package week01.datastructuretest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import week01.datastructure.Queue;
+
+
+public class QueueTest {
+
+ Queue queue = new Queue();
+
+ @Before
+ public void setUp() throws Exception {
+ for(int i=0;i<100;i++){
+ queue.enQueue(i);
+ }
+ }
+
+ @Test
+ public void testEnQueue() {
+ Assert.assertEquals(queue.size(), 100);
+ for(int i =0;i<100;i++){
+ queue.enQueue(i);
+ }
+ Assert.assertEquals(queue.size(), 200);
+ }
+
+ @Test
+ public void testDeQueue() {
+ for(int i =0;i<100;i++){
+ Assert.assertEquals(queue.deQueue(), i);
+ }
+
+ }
+
+ @Test
+ public void testIsEmpty() {
+ Assert.assertEquals(queue.isEmpty(), false);
+ for(int i=0;i<100;i++){
+ queue.deQueue();
+ }
+ Assert.assertEquals(queue.isEmpty(), true);
+ }
+
+ @Test
+ public void testSize() {
+ Assert.assertEquals(queue.size(), 100);
+ queue.enQueue(100);
+ Assert.assertEquals(queue.size(), 101);
+ queue.deQueue();
+ Assert.assertEquals(queue.size(), 100);
+ }
+
+}
diff --git a/group01/1814014897/zhouhui/src/week01/datastructuretest/StackTest.java b/group01/1814014897/zhouhui/src/week01/datastructuretest/StackTest.java
new file mode 100644
index 0000000000..b20119e69b
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week01/datastructuretest/StackTest.java
@@ -0,0 +1,71 @@
+package week01.datastructuretest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import week01.datastructure.Stack;
+
+
+public class StackTest {
+
+ Stack stack = new Stack();
+
+ @Before
+ public void setUp() throws Exception {
+ for(int i =0 ;i <100;i++){
+ stack.push(i);
+ }
+ }
+
+ @Test
+ public void testPush() {
+ Assert.assertEquals(stack.peek(), 99);
+ for(int i =0;i <200;i++){
+ stack.push(i);
+ }
+ Assert.assertEquals(stack.peek(), 199);
+ Assert.assertEquals(stack.size(), 300);
+ }
+
+ @Test
+ public void testPop() {
+ Assert.assertEquals(stack.pop(), 99);
+ Assert.assertEquals(stack.pop(), 98);
+ for(int i=0;i<98;i++){
+ stack.pop();
+ }
+ Assert.assertEquals(stack.size(), 0);
+ }
+
+ @Test
+ public void testPeek() {
+ for(int i=0;i<100;i++){
+ Assert.assertEquals(stack.peek(), 99);
+ Assert.assertEquals(stack.size(), 100);
+ }
+ stack.pop();
+ Assert.assertEquals(stack.peek(), 98);
+ Assert.assertEquals(stack.peek(), 98);
+ }
+
+ @Test
+ public void testIsEmpty() {
+ Assert.assertEquals(stack.isEmpty(), false);
+ for(int i =0 ;i <100;i++){
+ stack.pop();
+ }
+ Assert.assertEquals(stack.isEmpty(), true);
+ }
+
+ @Test
+ public void testSize() {
+ stack.push(100);
+ Assert.assertEquals(stack.size(), 101);
+ stack.pop();
+ Assert.assertEquals(stack.size(), 100);
+ stack.peek();
+ Assert.assertEquals(stack.size(), 100);
+ }
+
+}
diff --git a/group01/1814014897/zhouhui/src/week02/array/ArrayUtil.java b/group01/1814014897/zhouhui/src/week02/array/ArrayUtil.java
new file mode 100644
index 0000000000..dd939e7d2c
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week02/array/ArrayUtil.java
@@ -0,0 +1,222 @@
+package week02.array;
+
+/**
+ *
+ * @author Hui Zhou
+ * @version 1.0 2017-02-28
+ *
+ */
+
+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) return;
+
+ int mid = origin.length/2;
+ for(int i=0;iarray4[j+1]){
+ int sto = array4[j];
+ array4[j] = array4[j+1];
+ array4[j+1] = sto;
+ }
+ }
+ }
+ return array4;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+ if(size<0 || oldArray==null) return null;
+
+ int[] newArray = new int[oldArray.length + size];
+ for(int i=0;i parameters) {
+
+ /*
+
+ 0. 读取配置文件struts.xml
+
+ 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法
+
+ 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+
+ 3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters
+
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+
+ */
+
+ //读取配置文件struts.xml
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder;
+ Document doc = null;
+ View view = new View(); //实例化View(后面调用view,存储parameters以及jsp,最后return view)
+ try {
+ builder = factory.newDocumentBuilder();
+ File f = new File("src/week02/litestruts/struts.xml");
+ doc = builder.parse(f);
+ } catch (ParserConfigurationException|SAXException|IOException e) {
+ e.printStackTrace();
+ }
+
+ //根据actionName找到相对应的action
+ Element root = doc.getDocumentElement();
+ NodeList actionNode = root.getElementsByTagName("action");
+ Element action = null;
+ for(int i=0;i cls = Class.forName(actionClass);
+ Object obj = cls.newInstance();
+ Method setName = cls.getMethod("setName", String.class);
+ Method setPassword = cls.getMethod("setPassword", String.class);
+ setName.invoke(obj, parameters.get("name"));
+ setPassword.invoke(obj, parameters.get("password"));
+
+ //通过反射调用对象的exectue 方法,并获得返回值
+ Method execute = cls.getMethod("execute");
+ String exe_val = (String) execute.invoke(obj);
+
+ //通过反射找到对象的所有getter方法,通过反射来调用
+ Method[] met = cls.getDeclaredMethods();
+ List list = new LinkedList();
+ for(int i=0;i param = new HashMap<>();
+ for(int i=0;i 配置,以及execute的返回值,确定哪一个jsp,放到View对象的jsp字段中
+ if(exe_val.equals("success"))
+ view.setJsp("/jsp/homepage.jsp");
+ else view.setJsp("/jsp/showLogin.jsp");
+
+ } catch (ClassNotFoundException|InstantiationException|IllegalAccessException
+ |NoSuchMethodException|SecurityException|IllegalArgumentException|InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
+ return view;
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week02/litestruts/StrutsTest.java b/group01/1814014897/zhouhui/src/week02/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..e65f6525bd
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week02/litestruts/StrutsTest.java
@@ -0,0 +1,41 @@
+package week02.litestruts;
+
+import java.util.*;
+import org.junit.*;
+
+/**
+ * @author Hui Zhou
+ * @version 1.0 2017-02-28
+ */
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week02/litestruts/View.java b/group01/1814014897/zhouhui/src/week02/litestruts/View.java
new file mode 100644
index 0000000000..3043fb5d5a
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week02/litestruts/View.java
@@ -0,0 +1,28 @@
+package week02.litestruts;
+
+import java.util.Map;
+
+/**
+ * @author Hui Zhou
+ * @version 1.0 2017-02-28
+ */
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week02/litestruts/struts.xml b/group01/1814014897/zhouhui/src/week02/litestruts/struts.xml
new file mode 100644
index 0000000000..f449db14dd
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week02/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/group01/1814014897/zhouhui/src/week03/download/DownloadThread.java b/group01/1814014897/zhouhui/src/week03/download/DownloadThread.java
new file mode 100644
index 0000000000..58c25cdabc
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week03/download/DownloadThread.java
@@ -0,0 +1,38 @@
+package week03.download;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+import week03.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+ Connection conn;
+ int startPos;
+ int endPos;
+ CyclicBarrier barrier;
+
+ public DownloadThread( Connection conn, int startPos, int endPos,CyclicBarrier barrier){
+ this.conn = conn;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ this.barrier = barrier;
+ }
+
+ @Override
+ public void run(){
+ try {
+ byte[] piece = conn.read(startPos, endPos);
+ System.out.println("此线程下载总长度:"+piece.length+",范围:"+startPos+"~"+endPos);
+ RandomAccessFile m = new RandomAccessFile("download.jpg", "rw");
+ m.seek(startPos);
+ m.write(piece);
+ m.close();
+ barrier.await();
+ } catch (IOException|InterruptedException|BrokenBarrierException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/group01/1814014897/zhouhui/src/week03/download/FileDownloader.java b/group01/1814014897/zhouhui/src/week03/download/FileDownloader.java
new file mode 100644
index 0000000000..aa15899309
--- /dev/null
+++ b/group01/1814014897/zhouhui/src/week03/download/FileDownloader.java
@@ -0,0 +1,93 @@
+package week03.download;
+
+import java.util.concurrent.CyclicBarrier;
+
+import week03.download.api.Connection;
+import week03.download.api.ConnectionManager;
+import week03.download.api.DownloadListener;
+import week03.download.impl.ConnectionManagerImpl;
+
+
+public class FileDownloader {
+
+ String url;
+
+ DownloadListener listener;
+
+ ConnectionManager cm;
+
+ CyclicBarrier cb;
+
+ int threadNum = 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方法
+
+ // 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
+ Connection conn = null;
+
+ cb = new CyclicBarrier(3,new Runnable() {
+
+ @Override
+ public void run() {
+ listener.notifyFinished();
+ }
+ });
+
+ try {
+ cm = new ConnectionManagerImpl();
+ conn = cm.open(this.url);
+ int length = conn.getContentLength();
+ conn.close();
+
+ for(int i=0;isize ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size);
+ }
+
+ public Object get(int index){
+ checkIndexPosition(index);
+ Node pos = head;
+ for(int i = 0;i < index;i++){
+ pos = pos.next;
+ }
+ return pos.data;
+ }
+
+ public Object remove(int index){
+ checkIndexPosition(index);
+ Node element = head;
+ if(index == 0){
+ head = head.next;
+ }else{
+ Node pos = head;
+ for(int i = 0;i < index - 1;i++){
+ pos = pos.next;
+ }
+ element = pos.next;
+ pos.next = pos.next.next;
+ }
+ size--;
+ return element.data;
+ }
+
+ private void checkIndexPosition(int index) {
+ if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size);
+ }
+
+
+ public int size(){
+ return size;
+ }
+
+ public void addFirst(Object o){
+ add(0,o);
+ }
+
+ public void addLast(Object o){
+ add(size,o);
+ }
+
+ public Object removeFirst(){
+ return remove(0);
+ }
+
+ public Object removeLast(){
+ return remove(size-1);
+ }
+
+ public Iterator iterator(){
+ return new LinkedListIterator();
+ }
+
+ class LinkedListIterator implements Iterator{
+
+ private Node node = head;
+ private int pos = 0;
+ @Override
+ public boolean hasNext() {
+ return pos < size;
+ }
+
+ @Override
+ public Object next() {
+ pos++;
+ if(pos != 1){
+ node = node.next;
+ }
+ return node.data;
+ }
+ }
+
+ private static class Node{
+ Object data;
+ Node next;
+ public Node(Object data){
+ this.data = data;
+ next = null;
+ }
+ }
+ /**
+ * 把该链表逆置
+ * 例如链表为 3->7->10 , 逆置后变为 10->7->3
+ */
+ public void reverse(){
+ if(size == 0) return;
+
+ for(int i=1;i5->7->8 , 删除以后的值为 7->8
+ * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+ */
+ public void removeFirstHalf(){
+ if(size == 0) return;
+
+ int removeNum = size/2;
+ for(int i=0;i size || i<0 || i>=size) return;
+
+ for(int k=i;k<(length+i);k++){
+ remove(i);
+ }
+ }
+ /**
+ * 假定当前链表和list均包含已升序排列的整数
+ * 从当前链表中取出那些list所指定的元素
+ * 例如当前链表 = 11->101->201->301->401->501->601->701
+ * listB = 1->3->4->6
+ * 返回的结果应该是[101,301,401,601]
+ * @param list
+ */
+ public int[] getElements(LinkedList list){
+ if(list == null) return new int[0];
+
+ int[] targetList = new int[list.size];
+ for(int i=0;i min && (int)get(i) < max){
+ remove(i--);
+ }
+ }
+ */
+
+ //遍历到最小值和最大值处并记录位置,最后调用remove(int i,int length)进行范围内的删除。
+ int minPos = 0;
+ int maxPos = 0;
+ boolean exec = true;
+ for(int i=0;i min) {
+ minPos = i;
+ exec = false;
+ } else if((int)get(i) >max){
+ maxPos = i;
+ break;
+ }
+ }
+ remove(minPos, maxPos - minPos);
+ }
+
+ /**
+ * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
+ * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
+ * @param list
+ */
+ public LinkedList intersection( LinkedList list){
+ LinkedList newList = new LinkedList();
+ for(int i=0;i
+
+
+
+
+
+
+
diff --git a/group04/564451732/.gitignore b/group01/2137642225/work02/.gitignore
similarity index 100%
rename from group04/564451732/.gitignore
rename to group01/2137642225/work02/.gitignore
diff --git a/group01/2137642225/work02/.project b/group01/2137642225/work02/.project
new file mode 100644
index 0000000000..e340a1dc5b
--- /dev/null
+++ b/group01/2137642225/work02/.project
@@ -0,0 +1,17 @@
+
+
+ work02
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/group01/2137642225/work02/.settings/org.eclipse.jdt.core.prefs b/group01/2137642225/work02/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..838bd9d694
--- /dev/null
+++ b/group01/2137642225/work02/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/group01/2137642225/work02/README.md b/group01/2137642225/work02/README.md
new file mode 100644
index 0000000000..ce9e536748
--- /dev/null
+++ b/group01/2137642225/work02/README.md
@@ -0,0 +1 @@
+-- 实现数组工具类和读取xml
\ No newline at end of file
diff --git a/group01/2137642225/work02/src/com/coderising/array/ArrayUtil.java b/group01/2137642225/work02/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..f760a015f9
--- /dev/null
+++ b/group01/2137642225/work02/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,236 @@
+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 > 1) {
+ int len = origin.length;
+ int temp;
+ for(int left = 0,right = len - 1; left < right; left++,right = len - left - 1){
+ temp = origin[left];
+ origin[left] = origin[right];
+ origin[right] = 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[] newArray = null;
+ if (oldArray != null && oldArray.length > 0) {
+ int[] indexArray = new int[oldArray.length];
+ int j = 0;
+ for (int i = 0; i < oldArray.length; i++) {
+ if(oldArray[i] != 0){
+ indexArray[j++] = i;
+ }
+ }
+ newArray = new int[j];
+ for (int i = 0; i < j; i++) {
+ newArray[i] = oldArray[indexArray[i]];
+ }
+ indexArray = null;
+ }
+ 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){
+ if(array1 == null || array1.length <= 0){
+ return array2;
+ }
+ if(array2 == null || array2.length <= 0){
+ return array1;
+ }
+ int[] tempArray = new int[array1.length + array2.length];
+ int i = 0,j = 0,k = 0;
+ for (; i < array1.length && j < array2.length; ) {
+ if (array1[i] > array2[j]) {
+ tempArray[k++] = array2[j++];
+ }
+ else if(array1[i] < array2[j]){
+ tempArray[k++] = array1[i++];
+ }
+ else {
+ tempArray[k++] = array1[i++];
+ j++;
+ }
+ }
+ // 以array1为结束点
+ if(array1[array1.length - 1] > array2[array2.length - 1]){
+ for (; i < array1.length;) {
+ tempArray[k++] = array1[i++];
+ }
+ } else { // 以array2为结束点
+ for (; j < array2.length;) {
+ tempArray[k++] = array1[j++];
+ }
+ }
+ int[] mergeArray = new int[k];
+ for (int l = 0; l < mergeArray.length; l++) {
+ mergeArray[l] = tempArray[l];
+ }
+ tempArray = null;
+ return mergeArray;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+ if(size <= 0){
+ throw new RuntimeException("size大于0");
+ }
+ int[] newArray = null;
+ if(oldArray != null && oldArray.length > 0){
+ newArray = new int[oldArray.length + size];
+ for (int i = 0; i < oldArray.length; i++) {
+ newArray[i] = oldArray[i];
+ }
+ }
+ return newArray;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列
+ * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13]
+ * max = 1, 则返回空数组 []
+ * @param max
+ * @return
+ */
+ public int[] fibonacci(int max){
+ if(max <= 1){
+ return new int[0];
+ }
+ int[] tempArray = new int[max];
+ int i = 0;
+ tempArray[i++] = 1;
+ tempArray[i] = 1;
+ while(tempArray[i] < max){
+ i++;
+ tempArray[i] = tempArray[i - 1] + tempArray[i - 2];
+ }
+ int[] array = new int[i];
+ for (int j = 0; j < array.length; j++) {
+ array[j] = tempArray[j];
+ }
+ tempArray = null;
+ return array;
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public int[] getPrimes(int max){
+ if(max <= 2){
+ return new int[0];
+ }
+ int[] tempArray = new int[max];
+ int j = 0;
+ for (int i = 2; i < max; i++) {
+ if(isPrime(i)){
+ tempArray[j++] = i;
+ }
+ }
+ int[] array = new int[j];
+ for (int i = 0; i < j; i++) {
+ array[i] = tempArray[i];
+ }
+ tempArray = null;
+ return array;
+ }
+
+ private boolean isPrime(int i) {
+ for (int j = 2; j < i; j++) {
+ if(i % j == 0){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public int[] getPerfectNumbers(int max){
+ if(max <= 2){
+ return new int[0];
+ }
+ int[] tempArray = new int[max];
+ int j = 0;
+ for (int i = 3; i < max; i++) {
+ if(isPerfectNumber(i)){
+ tempArray[j++] = i;
+ }
+ }
+ int[] array = new int[j];
+ for (int i = 0; i < j; i++) {
+ array[i] = tempArray[i];
+ }
+ tempArray = null;
+ return array;
+ }
+
+ private boolean isPerfectNumber(int num) {
+ int sum = 1;
+ for(int i = 2; i < num; i++){
+ if(num % i == 0){
+ sum += i;
+ }
+ }
+ if(sum == num){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public String join(int[] array, String seperator){
+ char[] chars = new char[array.length<<1];
+ for (int i = 0,j = 1; i < chars.length; i+=2,j+=2) {
+ chars[i] = (char) (array[i>>1] + 48);
+ chars[j] = seperator.charAt(0);
+ }
+ return new String(chars, 0, chars.length - 1);
+ }
+
+
+}
diff --git a/group01/2137642225/work02/src/com/coderising/litestruts/LoginAction.java b/group01/2137642225/work02/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..1005f35a29
--- /dev/null
+++ b/group01/2137642225/work02/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/group01/2137642225/work02/src/com/coderising/litestruts/Struts.java b/group01/2137642225/work02/src/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..ab57e27477
--- /dev/null
+++ b/group01/2137642225/work02/src/com/coderising/litestruts/Struts.java
@@ -0,0 +1,338 @@
+package com.coderising.litestruts;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+
+@SuppressWarnings("unchecked")
+public class Struts {
+
+ public static View runAction(String actionName, Map parameters) {
+
+ if(actionName == null || actionName.trim().equals("")){
+ throw new RuntimeException("传入的actionName不能为null或者空");
+ }
+
+ // 0. 读取配置文件struts.xml ok
+ URL resource = Struts.class.getResource("/com/coderising/litestruts");
+ String path = "";
+ try {
+ path = URLDecoder.decode(resource.getPath(), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ Map> actionMap = xmlParse(path + File.separator + "struts.xml");
+
+ // 找到访问的action通过actionName
+ Map action = findAction(actionName,actionMap);
+
+ //1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ //据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ //("name"="test" , "password"="1234") ,
+ //那就应该调用 setName和setPassword方法
+ // 实例化对象
+ String className = (String) action.get("class");
+ Class> clazz = getActionClassByClassName(className);
+ Object actionObject = buildActionObject(clazz,parameters);
+
+ //2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+ // 执行访问的方法
+ String result = (String) executeAccessMethod(actionObject,clazz,"execute");
+
+ //3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ //通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ //放到View对象的parameters
+ Map parameterMap = getActionObjectParameters(actionObject,clazz);
+
+ //4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ //放到View对象的jsp字段中。
+ String jsp = getViewPath(action,result);
+ View v = buildView(jsp,parameterMap);
+
+ return v;
+ }
+
+ private static Class> getActionClassByClassName(String className) {
+
+ if(className == null || className.trim().equals("")){
+ throw new RuntimeException("没有配置action的class属性");
+ }
+
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 获取配置文件中视图的路径
+ * @param action
+ * @param result
+ * @return
+ */
+ private static String getViewPath(Map action, String result) {
+
+ if(result != null && !result.trim().equals("")){
+
+ List